php preg match find string inside " " with limit - php

This is my text:
pagination},queryId:"472f257a40c653c64c666ce877d59d2b", val:"598f257a40c653c64c666ce877d59d2b"
I need to find 472f257a40c653c64c666ce877d59d2b and 598f257a40c653c64c666ce877d59d2b.
These are all between ". I need ONLY strings between " ", and which don't exceds 32.
Here is my code:
preg_match_all('/"^(.*?){32}$"/mis', $get, $results);

You could use :"\K[a-f\d]{32}(?=")
Explanation
Match :"
Reset the starting point of the reported match \K
Match characters from a to f and from 0 to 9 [a-f\d]{32}
A positive lookahead that asserts what follows is a " (?=")
For example:
$re = '/:"\K[a-f\d]{32}(?=")/';
$str = 'pagination},queryId:"472f257a40c653c64c666ce877d59d2b", val:"598f257a40c653c64c666ce877d59d2b"';
preg_match_all($re, $str, $matches);
var_dump($matches[0]);
That would result in:
array(2) {
[0]=>
string(32) "472f257a40c653c64c666ce877d59d2b"
[1]=>
string(32) "598f257a40c653c64c666ce877d59d2b"
}
Output php example

Regex: "([a-z0-9]{32})" or (?<=")[a-z0-9]{32}(?=")
$text = "pagination},queryId:\"472f257a40c653c64c666ce877d59d2b\", val:\"598f257a40c653c64c666ce877d59d2b\"";
preg_match_all("/\"([a-z0-9]{32})\"/", $text, $match);
print_r($match);
Output:
Array
(
[0] => Array
(
[0] => "472f257a40c653c64c666ce877d59d2b"
[1] => "598f257a40c653c64c666ce877d59d2b"
)
[1] => Array
(
[0] => 472f257a40c653c64c666ce877d59d2b
[1] => 598f257a40c653c64c666ce877d59d2b
)
)

Related

Use a RegEx in PHP to find and save multiple occurences in a string

I got this string:
if(conditionA==valueA-AND-conditionB==valueB-OR-conditionC==valueC)
The String can contain indefinite occurences of conditions.
and I want an array that contains:
array(3) {
[0]=>
string(...) "conditionA==valueA"
[1]=>
string(...) "conditionB==valueB"
[2]=>
string(...) "conditionC==valueC"
}
I am currently using this pattern:
preg_match("/^if\((.+)-(.+)\)/U", $current_step_data_exploded[0], $if_statements);
Also, I need the "ANDs" and "ORs" so I can further check the statements.
My RegEex doesn't deliver. Can somebody help me?
$string = "if(conditionA==valueA-AND-conditionB==valueB-OR-conditionC==valueC)";
$match = preg_match('/^if\((.+)\)$/', $string, $if);
if ($match) {
$conditions = preg_split('/\-(AND|OR)\-/', $if[1], -1, PREG_SPLIT_DELIM_CAPTURE);
print_r($conditions);
} else {
echo "no matches.";
}
will output:
Array
(
[0] => conditionA==valueA
[1] => AND
[2] => conditionB==valueB
[3] => OR
[4] => conditionC==valueC
)
You could make use of the \G anchor and a capture group:
(?:\bif\((?=[^()]*\))|\G(?!^))(.*?==.*?)(?:-(?:AND|OR)-|\)$)
Explanation
(?: Non capture group
\bif\((?=[^()]*\) Match if( and assert a closing )
| Or
\G(?!^) Assert the current position at the end of the previous match, not at the start
) Close the non capture group
(.*?==.*?)
(?:-(?:AND|OR)-|\)$) Match one of -AND- -OR-or)` and the end of the string
Regex demo | PHP demo
Example
$re = '/(?:\bif\((?=[^()]*\))|\G(?!^))(.*?==.*?)(?:-(?:AND|OR)-|\)$)/';
$str = 'if(conditionA==valueA-AND-conditionB==valueB-OR-conditionC==valueC)';
preg_match_all($re, $str, $matches);
print_r($matches[1]);
Output
Array
(
[0] => conditionA==valueA
[1] => conditionB==valueB
[2] => conditionC==valueC
)

php regular expression: how to correctly escape characters?

How to write preg_match, to match string *My* ?
This doesn't work:
$ptn = "/\*(.*)\*/";
$str = "*My*";
preg_match($ptn, $str, $matches);
print_r($matches);
because it outputs:
Array
(
[0] => *My*
[1] => *My*
)
instead of:
Array
(
[0] => *My*
[1] => My
)
Works fine here:
php > preg_match('/\*(.*)\*/', '*My*', $matches);
php > var_dump($matches);
array(2) {
[0]=>
string(4) "*My*"
[1]=>
string(2) "My"
}
Remember that the $matches array will ALWAYS contain the entire matched string in position 0, then the individal matches in slots 1+.

Regex to get repeating matches within a match

I have this sample string in a source:
#include_plugin:PluginName param1=value1 param2=value2#
What I want is to find all occurances of #include_plugin:*# from a source with a result of the PluginName and each paramN=valueN.
At this moment I'm fiddling with something like this (and have tried many variants): /#include_plugin:(.*\b){1}(.*\=.*){0,}#/ (using this resource). Unfortunately I can't seem to define a pattern which is giving me the result I want. Any suggestions?
Update with example:
Say I have this string in a .tpl-file. #include_plugin:BestSellers limit=5 fromCategory=123#
I want it to return an array with:
0 => BestSellers,
1 => limit=5 fromCategory=123
Or even better (if possible):
0 => BestSellers,
1 => limit=5,
2 => fromCategory=123
You can do it in 2 steps. First capture the line with a regex, then explode the parameters into an array:
$subject = '#include_plugin:PluginName param1=value1 param2=value2#';
$pattern = '/#include_plugin:([a-z]+)( .*)?#/i';
preg_match($pattern, $subject, $matches);
$pluginName = $matches[1];
$pluginParams = isset($matches[2])?explode(' ', trim($matches[2])):array();
You can use this regex:
/#include_plugin:([a-zA-Z0-9]+)(.*?)#/
The PluginName is in the first capturing group, and the parameters are in the second capturing group. Note that the parameters, if any, has a leading spaces.
It is not possible to write a regex to extract to your even better case, unless the maximum number of parameters in known.
You can do extra processing by first trimming leading and trailing spaces, then split along /\s+/.
I'm not sure of your character-set that your PluginName can contain, or the parameters/values, but in case they are limited you can use the following regex:
/#include_plugin:((?:\w+)(?:\s+[a-zA-Z0-9]+=[a-zA-Z0-9]+)*)#/
This will capture the plugin name followed by any list of alpha-numeric parameters with their values. The output can be seen with:
<?
$str = '#include_plugin:PluginName param1=value1 param2=value2#
#include_plugin:BestSellers limit=5 fromCategory=123#';
$regex = '/#include_plugin:((?:\w+)(?:\s+[a-zA-Z0-9]+=[a-zA-Z0-9]+)*)#/';
$matches = array();
preg_match_all($regex, $str, $matches);
print_r($matches);
?>
This will output:
Array
(
[0] => Array
(
[0] => #include_plugin:PluginName param1=value1 param2=value2#
[1] => #include_plugin:BestSellers limit=5 fromCategory=123#
)
[1] => Array
(
[0] => PluginName param1=value1 param2=value2
[1] => BestSellers limit=5 fromCategory=123
)
)
To get the array in the format you need, you can iterate through the results with:
$plugins = array();
foreach ($matches[1] as $match) {
$plugins[] = explode(' ', $match);
}
And now you'll have the following in $plugins:
Array
(
[0] => Array
(
[0] => PluginName
[1] => param1=value1
[2] => param2=value2
)
[1] => Array
(
[0] => BestSellers
[1] => limit=5
[2] => fromCategory=123
)
)
$string = "#include_plugin:PluginName1 param1=value1 param2=value2# #include_plugin:PluginName2#";
preg_match_all('/#include_plugin:([a-zA-Z0-9]+)\s?([^#]+)?/', $string, $matches);
var_dump($matches);
is this what you are looking for?
array(3) {
[0]=>
array(2) {
[0]=>
string(55) "#include_plugin:PluginName1 param1=value1 param2=value2"
[1]=>
string(27) "#include_plugin:PluginName2"
}
[1]=>
array(2) {
[0]=>
string(11) "PluginName1"
[1]=>
string(11) "PluginName2"
}
[2]=>
array(2) {
[0]=>
string(27) "param1=value1 param2=value2"
[1]=>
string(0) ""
}
}
This Regex will give you multiple groups, one for each plugin.
((?<=#include_plugin:)(.+))

PHP's preg_match() and preg_match_all() functions

What do the preg_match() and preg_match_all() functions do and how can I use them?
preg_match stops looking after the first match. preg_match_all, on the other hand, continues to look until it finishes processing the entire string. Once match is found, it uses the remainder of the string to try and apply another match.
http://php.net/manual/en/function.preg-match-all.php
Both preg_match and preg_match_all functions in PHP use Perl compatible regular expressions.
You can watch this series to fully understand Perl compatible regular expressions: https://www.youtube.com/watch?v=GVZOJ1rEnUg&list=PLfdtiltiRHWGRPyPMGuLPWuiWgEI9Kp1w
preg_match($pattern, $subject, &$matches, $flags, $offset)
The preg_match function is used to search for a particular $pattern in a $subject string and when the pattern is found the first time, it stops searching for it. It outputs matches in the $matches, where $matches[0] will contain the text that matched the full pattern, $matches[1] will have the text that matched the first captured parenthesized sub-pattern, and so on.
Example of preg_match()
<?php
preg_match(
"|<[^>]+>(.*)</[^>]+>|U",
"<b>example: </b><div align=left>this is a test</div>",
$matches
);
var_dump($matches);
Output:
array(2) {
[0]=>
string(16) "<b>example: </b>"
[1]=>
string(9) "example: "
}
preg_match_all($pattern, $subject, &$matches, $flags)
The preg_match_all function searches for all the matches in a string and outputs them in a multi-dimensional array ($matches) ordered according to $flags. When no $flags value is passed, it orders results so that $matches[0] is an array of full pattern matches, $matches[1] is an array of strings matched by the first parenthesized sub-pattern, and so on.
Example of preg_match_all()
<?php
preg_match_all(
"|<[^>]+>(.*)</[^>]+>|U",
"<b>example: </b><div align=left>this is a test</div>",
$matches
);
var_dump($matches);
Output:
array(2) {
[0]=>
array(2) {
[0]=>
string(16) "<b>example: </b>"
[1]=>
string(36) "<div align=left>this is a test</div>"
}
[1]=>
array(2) {
[0]=>
string(9) "example: "
[1]=>
string(14) "this is a test"
}
}
A concrete example:
preg_match("/find[ ]*(me)/", "find me find me", $matches):
$matches = Array(
[0] => find me
[1] => me
)
preg_match_all("/find[ ]*(me)/", "find me find me", $matches):
$matches = Array(
[0] => Array
(
[0] => find me
[1] => find me
)
[1] => Array
(
[0] => me
[1] => me
)
)
preg_grep("/find[ ]*(me)/", ["find me find me", "find me findme"]):
$matches = Array
(
[0] => find me find me
[1] => find me findme
)

extract every occurrence on string

I have a string of the form "a-b""c-d""e-f"...
Using preg_match, how could I extract them and get an array as:
Array
(
[0] =>a-b
[1] =>c-d
[2] =>e-f
...
[n-times] =>xx-zz
)
Thanks
You can do:
$str = '"a-b""c-d""e-f"';
if(preg_match_all('/"(.*?)"/',$str,$m)) {
var_dump($m[1]);
}
Output:
array(3) {
[0]=>
string(3) "a-b"
[1]=>
string(3) "c-d"
[2]=>
string(3) "e-f"
}
Regexp are not always the fastest solution:
$string = '"a-b""c-d""e-f""g-h""i-j"';
$string = trim($string, '"');
$array = explode('""',$string);
print_r($array);
Array ( [0] => a-b [1] => c-d [2] => e-f [3] => g-h [4] => i-j )
Here's my take on it.
$string = '"a-b""c-d""e-f"';
if ( preg_match_all( '/"(.*?)"/', $string, $matches ) )
{
print_r( $matches[1] );
}
And a breakdown of the pattern
" // match a double quote
( // start a capture group
. // match any character
* // zero or more times
? // but do so in an ungreedy fashion
) // close the captured group
" // match a double quote
The reason you look in $matches[1] and not $matches[0] is because preg_match_all() returns each captured group in indexes 1-9, whereas the entire pattern match is at index 0. Since we only want the content in the capture group (in this case, the first capture group), we look at $matches[1].

Categories