PHP preg_match meaning and issue - php

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.

Related

Match multiple strings

I'm trying to see whether or not 2 strings match.
example: 1234.5678.9012.3456 => 5678.1234.3456 = match
This matches because the second string of number are also in the first one. I did this with the following code:
<?php
$haystack = '1234.5678.9012.3456';
$needle = '5678.1234.3456';
$regex = '/(?=.*'. str_replace(".",")(?=.*",$needle) .').*$/';
// regex looks like this /(?=.*5678)(?=.*1234)(?=.*3456).*$/
if(preg_match($regex, $haystack)){
echo "A match was found.";
} else {
echo "A match was not found.";
}
?>
Here is my problem, when there are duplicate numbers.
example: 1234.5678.9012.3456 => 5678.5678.3456 = dont match
1234.5678.5678.3456 => 5678.5678.3456 = match
The first example doesnt match because 5678 occurs twice but the first string only has 5678 once. In the second example 5678 occurs twice as well and therefor matches the second string.
My question: How could I change my regex,
You choose a very complicated way to do that. You can check what you want in a more simple way using array_diff:
var_dump(array_diff(explode('.', $needle), explode('.', $haystack)));
when the resulting array is empty the condition is true.
Try this:
<?php
$haystack = '1234.5678.9012.3456';
$needle = '5678.5678.3456';
$needle_array = explode(".", $needle);
//print_r($needle_array);
$haystack_array = explode(".", $haystack);
//print_r($haystack_array);
$intersect = array_intersect($needle_array, $haystack_array);
//print_r($intersect);
if(count($intersect) > 0){
echo "Match";
} else {
echo "Doesn't match";
}
?>

PHP check if two keywords occur in String

my challange explained on the following example: The keyword combination "gaming notebook" is given.
I want to check whether the two keywords occur in a string. The challange is that the string could look like this:
"Nice Gaming Notebook"
"Notebook for Gaming"
"Notebook for extreme Gaming"
I want my function to return true for all of the three strings. There is a tolerance of 3-4 words that can be between the word combination and as the examples show, I want it to work if the keywords are switched.
So my approach was the following, but it does not seem to work:
$keyword = strtolower("gaming notebook");
$parts = explode(" ", $keyword);
$string = strtolower("Which notebook for good gaming performance");
//point to end of the array
end($parts);
//fetch key of the last element of the array.
$lastElementKey = key($parts);
//iterate the array
$searchExpression = "";
foreach($parts as $k => $v) {
if($k != $lastElementKey) {
$searchExpression .= $v . "|";
} else {
$searchExpression .= $v;
}
}
if(preg_match_all('#\b('. $searchExpression .')\b#', $string, $matches) > 0) {
echo "Jep, keyword combination is in string";
} else {
echo "No, keyword combination is not in string";
}
You want to use something like CMU Sphinx or a natural language index in your database. (See http://dev.mysql.com/doc/refman/5.7/en/fulltext-natural-language.html) Doing a quick search of php libraries turned up "nlp-tools/nlp-tools," however, I have never used a pure php solution to accomplish what you are trying to do.
The solution using preg_match_all and array_intersect functions:
$keywordStr = "gaming notebook";
$string = "Which notebook for good gaming performance,it's my notebook";
$keywords = explode(" ", $keywordStr);
$parts = implode("|", $keywords);
preg_match_all("/\b$parts\b/i", $string, $matches);
// matched items should contain all needed keywords
if (count($keywords) == count(array_intersect($keywords, $matches[0]))) {
echo "Jep, keyword combination is in string";
} else {
echo "No, keyword combination is not in string";
}
<?php
$keyword = strtolower("gaming notebook");
$string = strtolower("Which notebooks for good gaming performance");
function check($keyword,$string){
$parts = explode(' ',$keyword);
$result = false;
$pattern = implode('|',$parts);
preg_match_all("(\b{$pattern}\b)",$string,$matches);
if(isset($matches[0])){
return true;
}
return false;
}
var_dump(check($keyword, $string));
$reg = "/(?:\b$kw1(?:\s+\w+){0,4}\s+$kw2\b)|(?:\b$kw2(?:\s+\w+){0,4}\s+$kw1\b)/";
if (preg_match($reg, $string)) {
echo "OK\n";
} else {
echo "KO\n";
}
This will echo OK when the 2 keywords occur in the string, in any order and separated by at most 4 words.
Explanation:
/
(?: : non capture group
\b$kw1 : keyword 1
(?:\s+\w+){0,4} : followed by 0 to 4 other word
\s+ : space(s)
$kw2\b : keyword 2
)
|
(?: : non capture group
\b$kw2 : keyword 2
(?:\s+\w+){0,4} : followed by 0 to 4 other word
\s+ : space(s)
$kw1\b : keyword 1
)
/

How to Rename Uppercase Each Words with dash, underscore, brackets and capital words?

I want to rename the following statement:
<?php
$sentence = "I-am-a-GOOD-programmer-(but-only-in-PHP)";
$do = ucwords($sentence);
echo $do;
?>
the above code will give output as:
I-am-a-GOOD-programmer-(but-only-in-php)
How do I get the output as:
I-Am-A-Good-Programmer-(But-Only-In-Php)
$sentence = "I-am-a-good-programmer-(but-only-in-PHP)";
$sentence = preg_replace_callback('/(^|[-(])(\w+)/', function ($match) { return $match[1] . ucwords($match[2]); }, $sentence );
var_dump($sentence);
will result in:
string(40) "I-Am-A-Good-Programmer-(But-Only-In-PHP)"
^|[-(] means the beginning or either a - or ( and can be easily expanded with any other chars you need, alternatively you could your \W, which means any non-word character.
\w+ means word-character (alphabetical characters).
<?php
$msg = 'I-am-a-good-programmer-(but-only-in-PHP)';
$msg_replaced = preg_replace_callback('#([^\w]*)?(\w+)([^\w]*)?#', function($matched)
{
return $matched[1] . ucwords($matched[2]) . $matched[3];
}, $msg);
echo $msg_replaced;//I-Am-A-Good-Programmer-(But-Only-In-PHP)
?>
Found a solution to the problem:
<?php
$sentence = "I-am-a-GOOD-programmer-(but-only-in-PHP)";
$sentence = str_replace("-"," ",$sentence);
$do = ucfirst($sentence);
echo $do;
?>
Its gives output as I desired:
I Am A Good Programmer (But Only In Php)

Cannot read the first letter

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.

How to detect more than one line break \n in PHP?

I need to detect more than one \n. Doesn't matter if it's 2 or 1000, as long as it's more than one \n. What would be the regex for this (if regex is necessary that is)?
EDIT
I am using this:
$pregmatch = preg_match('#\\n\\n+#', $locations);
if ($pregmatch > 0) {
echo 'more than one, this many: '.count($pregmatch);
} else
echo 'less than one';
but count($pregmatch) doesn't return the actual number of more than one \n detected. How can that be achieved?
Are you looking for more than 1 \n in general? if so:
if (preg_match_all('#\\n#', $string, $matches) > 1) {
//More than 1 \n
}
Or without regex:
if (substr_count($string, "\n") > 1) {
//More than 1 \n
}
Or even (but it's far less efficient):
$chars = count_chars($string);
if (isset($chars[ord("\n")]) && $chars[ord("\n")] > 1) {
//More than 1 \n
}
If in a row:
if (preg_match_all('#\\n\\n+#', $string, $matches) > 0) {
//More than 1 \\n in a row
}
Edit: So, based on your edit, I can summize two possibilities about what you want to know.
If you want to know the number of \n characters in a row (more than 1), you could do:
if (preg_match('#\\n\\n+#', $string, $match)) {
echo strlen($match[0]) . ' Consecutive \\n Characters Found!';
}
Or, if you wanted to know for each occurance:
if (preg_match_all('#\\n\\n+#', $string, $matches)) {
echo count($matches) . ' Total \\n\\n+ Matches Found';
foreach ($matches[0] as $key => $match) {
echo 'Match ' . $key . ' Has ' .
strlen($match) . ' Consecutive \\n Characters Found!';
}
}
Something like (doc):
preg_match_all("[\n]*", $yourString, $outArray)
preg_match_all will return a count of how many there were, as well as the matches in the outArray.
You need to provide the /m modifier so that the scan spans more than on line:
if (preg_match('/\n\n/m', $str)) {
echo "match";
} else {
echo "no match";
}
You can avoid using regex, saving CPU, here is an elegant and tricky way:
$text_parts = explode("\n", $original_string);
Now you can join it replacing line breaks with something elese:
$new_string = implode("<br />", $text_parts);
I hope this helps

Categories