Cannot read the first letter - php

I want to add a function to return whether the first letter is a capital or not from my last question.
Here's the code:
<?php
function isCapital($string) {
return $string = preg_match('/[A-Z]$/',$string{0});
}
$text = " Poetry. do you read poetry while flying? Many people find it relaxing to read on long flights. Poetry can be divided into several genres, or categories. ";
$sentences = explode(".", $text); $save = array();
foreach ($sentences as $sentence) {
if (count(preg_split('/\s+/', $sentence)) > 6) {
$save[] = $sentence. ".";
}
}
if( count( $save) > 0) {
foreach ($save as $nama){
if (isCapital($nama)){
print_r ($nama);
}
}
}
?>
The result should be...
Poetry can be divided into several genres, or categories.
...but it prints nothing. I need only the sentence that consists of more than 6 words and start with capital letter.

When you do the explode() function, you are leaving a space at the start of the string, which means that the leftmost character of $string will never be a capital letter--it will be a space. I would change the isCapital() function to the following:
function isCapital($string) {
return preg_match('/^\\s*[A-Z]/', $string) > 0;
}

You should be able to accomplish all of this through one regular expression, if you're so inclined:
preg_match_all('/((?=[A-Z])([^\s.!?]+\s+){5,}[^\s.!?]+[.!?])/', $string, $matches);
http://refiddle.com/2hz
Alternatively, remove the ! and ? from the character classes to only count . as a sentence delimiter.

Related

How to cut a text after a number of chars and obtain text sporead on multiple rows?

I have a very long text, and I need to cut the text after N chars, so that at the end I obtain a text, rendered on multiple rows, without any of the words being cut;
So, if a have a text with the lenght of a 1000 chars, which has been saved on 1 line, and I need to cut from 100 to 100 chars, at the end, I will get a text spread on 10 lines.
I tryed something, but I got stuck;
foreach does not work, the text is not seen a a array; also, i did not made sure to keep the words intact in my test;
Has anyone tryed this? Or is there any link with solution?
public static function cut_line_after_n_chars($str, $n = 70) {
$result = '';
$pos = 0;
foreach ($str as $c) {
$pos++;
if ($pos == $n) {
$result .= $c + '<br/>';
$pos = 0;
}
else
$result .= $c;
}
return $result;
}
It sounds like you need wordwrap.
http://php.net/manual/en/function.wordwrap.php
This allows you to break a string into an array of pieces without cutting off words. You can then format these pieces as you like.
EDIT
If you still need each of your lines to be 100 characters, you can use str_pad to add extra spaces onto each row.
Use explode() function to get array of words from your string.
$words = explode( ' ', $str );
$length = 0;
foreach( $words as $word ) {
// Your loop code goes here.
}

Group or list words by first 2 letters

I'd like to list/group words by the first two letters but I can't get my head around it. I guess I can I can do a substr() and check against while looping but I'm not sure if this is the way to do it.
Something like:
if (substr($word, 0, 2) == 'aa') {
echo $word;
}
What I'm trying to achieve:
Words get sorted first by their starting letter, e.g. A, B, C etc. On the A page you have the words sorted by the first 2 letters, e.g. aa, ab, ac etc.
An example for this is http://www.urbandictionary.com/browse.php?word=aa. They do exactly what I'm after.
Help/thoughts appreciated!
If you have a bunch of words, put them grouped together in an array.
for example:
<?php
$myWords = array ("hello", "hell", "ape", "word", "appel");
$myGroupedArr = array();
foreach ($myWords as $oneWord){
$firstTwo = substr($oneWord,0,2);
$myGroupedArr[$firstTwo][] = $oneWord;
}
echo "<pre>";
print_r($myGroupedArr);
echo "</pre>";
?>
I would sort not only by the first letter, but by the whole word, or at least by the first two letters.
Then, you can indeed use substr to get the first two letters of the first word. You can then enter the loop, and check the first two letters of the word in the loop, with the two letters you got before.
If they differ, you know you got a new group. You can echo a group header and store the new to letters to compare with in the following iterations.
// Words in a sorted array.
$words = array( ...... );
asort($words);
$currentGroup = '';
foreach ($words as $word)
{
$newGroup = substr($word, 0, 2);
if ($newGroup !== $currentGroup)
{
// A new group is starting.
echo "=== $newGroup ===<br/>";
$currentGroup = $newGroup;
}
echo $word . '<br/>';
}

Word counter: Doesn't seem to give the output I need (PHP)

here's the line of code that I came up with:
function Count($text)
{
$WordCount = str_word_count($text);
$TextToArray = explode(" ", $text);
$TextToArray2 = explode(" ", $text);
for($i=0; $i<$WordCount; $i++)
{
$count = substr_count($TextToArray2[$i], $text);
}
echo "Number of {$TextToArray2[$i]} is {$count}";
}
So, what's gonna happen here is that, the user will be entering a text, sentence or paragraph. By using substr_count, I would like to know the number of occurrences of the word inside the array. Unfortunately, the output the is not what I really need. Any suggestions?
I assume that you want an array with the word frequencies.
First off, convert the string to lowercase and remove all punctuation from the text. This way you won't get entries for "But", "but", and "but," but rather just "but" with 3 or more uses.
Second, use str_word_count with a second argument of 2 as Mark Baker says to get a list of words in the text. This will probably be more efficient than my suggestion of preg_split.
Then walk the array and increment the value of the word by one.
foreach($words as $word)
$output[$word] = isset($output[$word]) ? $output[$word] + 1 : 1;
If I had understood your question correctly this should also solve your problem
function Count($text) {
$TextToArray = explode(" ", $text); // get all space separated words
foreach($TextToArray as $needle) {
$count = substr_count($text, $needle); // Get count of a word in the whole text
echo "$needle has occured $count times in the text";
}
}
$WordCounts = array_count_values(str_word_count(strtolower($text),2));
var_dump($WordCounts);

PHP preg_match meaning and issue

Currently I have this code:
<?php
if (isset($_GET['id'])) {
$itemid = $_GET['id'];
$search = "$itemid";
$query = ucwords($search);
$string = file_get_contents('http://clubpenguincheatsnow.com/tools/newitemdatabase/items.php');
if($itemid=="")
{
echo "Please fill out the form.";
}
else
{
$string = explode('<br>',$string);
foreach($string as $row)
{
preg_match('/^(\D+)\s=\s(\d+)\s=\s(\D+)\s=\s(\d+)/', trim($row), $matches);
if(strstr($matches[1], $query))
{
echo "<a href='http://clubpenguincheatsnow.com/tools/newitemdatabase/info.php?id=$matches[2]'>";
echo $matches[1];
echo "</a><br>";
}
}
if($matches[1]=="")
{
echo "Item does not exist!";
}
}
}
else {
echo "Item does not exist!";
}
?>
What I want to know is what does this section mean? preg_match('/^(\D+)\s=\s(\d+)\s=\s(\D+)\s=\s(\d+)/', trim($row), $matches); mainly the /^(\D+)\s=\s(\d+)\s=\s(\D+)\s=\s(\d+)/ part is what I am wondering about.
Also, an issue that I have been having is how can I allow it to use numbers too? Because I have another file that has the data (http://clubpenguincheatsnow.com/tools/newitemdatabase/items.php) and it want it to grab everything, even the names with the numbers.
How do I do this though? Please help me! Any help would be VERY HIGHLY appreciated!
That is a regular expression.
The '^' matches the beginning of a string.
The '\D' matches any character that is not a digit.
The '\d' matches any digit.
The '\s' matches any whitespace.
The plus sign means that the previous character can occur multiple times.
So basically it would match all those lines in your file, except that last comma.
Blue = 1 = No = 20
That line would match the regex.
About your last question to allow numbers too, use this:
/^(.+)\s=\s(\d+)\s=\s(\D+)\s=\s(\d+)/
the code is a regular expression:
/^(\D+)\s=\s(\d+)\s=\s(\D+)\s=\s(\d+)/
the code will use the regular expression to cut the string um pieces and put in an array ($matches)
preg_match('/^(\D+)\s=\s(\d+)\s=\s(\D+)\s=\s(\d+)/', trim($row), $matches);
You shall use the code to see better
print_r($matches)
To find by name or by item number change the code
if(strstr($matches[1], $query))
to
if(isset($matches[1]) && (strstr($matches[1], $query) || $matches[2] == $query) )
Your code shall look like this...
if (isset($_GET['id'])) {
$itemid = $_GET['id'];
$search = "$itemid";
$query = ucwords($search);
$string = file_get_contents('http://clubpenguincheatsnow.com/tools/newitemdatabase/items.php');
if($itemid=="")
{
echo "Please fill out the form.";
}
else
{
$string = explode('<br>',$string);
foreach($string as $row)
{
preg_match('/^(\D+)\s=\s(\d+)\s=\s(\D+)\s=\s(\d+)/', trim($row), $matches);
if(isset($matches[1]) && (strstr($matches[1], $query) || $matches[2] == $query) )
{
echo "<a href='http://clubpenguincheatsnow.com/tools/newitemdatabase/info.php?id=$matches[2]'>";
echo $matches[1];
echo "</a><br>";
}
}
}
}
else {
echo "Item does not exist!";
}
/^(\D+)\s=\s(\d+)\s=\s(\D+)\s=\s(\d+)/
This regular expression will match any number of non-numeric character, followed by a whitespace character, followed by equals, and so on. For example, this
asd = 1 = yh = 23
To allow numbers in the names:
/^(\w+)\s=\s(\d+)\s=\s(\w+)\s=\s(\d+)/
To allow numbers and alpha-numeric chars in everything:
/^(\w+)\s=\s(\w+)\s=\s(\w+)\s=\s(\w+)/
To include spaces and ' too:
/^([\w\s']+)\s=\s([\w\s']+)\s=\s([\w\s']+)\s=\s([\w\s']+)/
The code, as said by Sena, is a regular expression. It is capturing four groups with "=" in between them.
group 1: (\D+) : any character that is not a digit one or more times
group 2: (\d+) : any character that is a digit one or more times
group 3: (\D+) : same as one
group 4: (\d+) : same as two.
So, it will match something like this: a = 1 = bc = 2
So, it is matching numbers, what do you want it to do? try print_r($matches) as suggested above.

Create acronym from a string containing only words

I'm looking for a way that I can extract the first letter of each word from an input field and place it into a variable.
Example: if the input field is "Stack-Overflow Questions Tags Users" then the output for the variable should be something like "SOQTU"
$s = 'Stack-Overflow Questions Tags Users';
echo preg_replace('/\b(\w)|./', '$1', $s);
the same as codaddict's but shorter
For unicode support, add the u modifier to regex: preg_replace('...../u',
Something like:
$s = 'Stack-Overflow Questions Tags Users';
if(preg_match_all('/\b(\w)/',strtoupper($s),$m)) {
$v = implode('',$m[1]); // $v is now SOQTU
}
I'm using the regex \b(\w) to match the word-char immediately following the word boundary.
EDIT:
To ensure all your Acronym char are uppercase, you can use strtoupper as shown.
Just to be completely different:
$input = 'Stack-Overflow Questions Tags Users';
$acronym = implode('',array_diff_assoc(str_split(ucwords($input)),str_split(strtolower($input))));
echo $acronym;
$initialism = preg_replace('/\b(\w)\w*\W*/', '\1', $string);
If they are separated by only space and not other things. This is how you can do it:
function acronym($longname)
{
$letters=array();
$words=explode(' ', $longname);
foreach($words as $word)
{
$word = (substr($word, 0, 1));
array_push($letters, $word);
}
$shortname = strtoupper(implode($letters));
return $shortname;
}
Regular expression matching as codaddict says above, or str_word_count() with 1 as the second parameter, which returns an array of found words. See the examples in the manual. Then you can get the first letter of each word any way you like, including substr($word, 0, 1)
The str_word_count() function might do what you are looking for:
$words = str_word_count ('Stack-Overflow Questions Tags Users', 1);
$result = "";
for ($i = 0; $i < count($words); ++$i)
$result .= $words[$i][0];
function initialism($str, $as_space = array('-'))
{
$str = str_replace($as_space, ' ', trim($str));
$ret = '';
foreach (explode(' ', $str) as $word) {
$ret .= strtoupper($word[0]);
}
return $ret;
}
$phrase = 'Stack-Overflow Questions IT Tags Users Meta Example';
echo initialism($phrase);
// SOQITTUME
$s = "Stack-Overflow Questions IT Tags Users Meta Example";
$sArr = explode(' ', ucwords(strtolower($s)));
$sAcr = "";
foreach ($sArr as $key) {
$firstAlphabet = substr($key, 0,1);
$sAcr = $sAcr.$firstAlphabet ;
}
using answer from #codaddict.
i also thought in a case where you have an abbreviated word as the word to be abbreviated e.g DPR and not Development Petroleum Resources, so such word will be on D as the abbreviated version which doesn't make much sense.
function AbbrWords($str,$amt){
$pst = substr($str,0,$amt);
$length = strlen($str);
if($length > $amt){
return $pst;
}else{
return $pst;
}
}
function AbbrSent($str,$amt){
if(preg_match_all('/\b(\w)/',strtoupper($str),$m)) {
$v = implode('',$m[1]); // $v is now SOQTU
if(strlen($v) < 2){
if(strlen($str) < 5){
return $str;
}else{
return AbbrWords($str,$amt);
}
}else{
return AbbrWords($v,$amt);
}
}
}
As an alternative to #user187291's preg_replace() pattern, here is the same functionality without needing a reference in the replacement string.
It works by matching the first occurring word characters, then forgetting it with \K, then it will match zero or more word characters, then it will match zero or more non-word characters. This will consume all of the unwanted characters and only leave the first occurring word characters. This is ideal because there is no need to implode an array of matches. The u modifier ensures that accented/multibyte characters are treated as whole characters by the regex engine.
Code: (Demo)
$tests = [
'Stack-Overflow Questions Tags Users',
'Stack Overflow Close Vote Reviewers',
'Jean-Claude Vandàmme'
];
var_export(
preg_replace('/\w\K\w*\W*/u', '', $tests)
);
Output:
array (
0 => 'SOQTU',
1 => 'SOCVR',
2 => 'JCV',
)

Categories