Error with php regular expression - php

i have this code:
$text = "###12###hello###43###good###113###thefinalstring";
preg_match_all('/(.*?)###(\d*)###(.*?)/is', $text, $matches, PREG_SET_ORDER);
If I dump $matches, why there is not "thefinalstring" anywhere?
Where is the error in the regular expression?
Thanks

(.*?)###(\d*)###(.*?)([a-zA-Z]*)
Use this regex

Have a try with:
$text = "###12###hello###43###good###113###thefinalstring";
preg_match_all('/###(\d*)###([^#]*)/is', $text, $matches, PREG_SET_ORDER);
print_r($matches);
output:
Array
(
[0] => Array
(
[0] => ###12###hello
[1] => 12
[2] => hello
)
[1] => Array
(
[0] => ###43###good
[1] => 43
[2] => good
)
[2] => Array
(
[0] => ###113###thefinalstring
[1] => 113
[2] => thefinalstring
)
)

Related

A regular expression to match a single character followed by numbers and ends with 'c'

I need a regex for the following pattern:
a single character from [e-g] followed by one or more numbers that ends with character 'c'.
for example
e123f654g933c
expected result:
Array
(
[0] => Array
(
[0] => e123
[1] => f654
[2] => g933
)
)
or
e123f654g933ce99f77g66c
expected result:
Array
(
[0] => Array
(
[0] => e123
[1] => f654
[2] => g933
),
[1] => Array
(
[0] => e99
[1] => f77
[2] => g66
)
)
I tried using the following but I don't know what to do with 'c' part.
I used this ([e-g]{1}[0-9]{1,}c)+ but it fails.
$subject="e123f654g933ce99f786g776c";
preg_match_all('/[e-g]{1}[0-9]{1,}/', $subject, $match);
print '<pre>' . print_r($match,1) . '</pre>';
Array
(
[0] => Array
(
[0] => e123
[1] => f654
[2] => g933
[3] => e99
[4] => f786
[5] => g776
)
)
thanks.
I couldn't manage to generate your multi dimensional output array via a single regex function call.
Code (Demo)
$strings = [
'e123f654g933c',
'e123f654g933ce99f77g66c'
];
foreach ($strings as $string) {
var_export(
array_map(
function($v) {
return preg_match_all('/[e-g]\d+/', $v, $out2) ? $out2[0] : []; // split the groups by string format
// or return preg_split('/\d+\K/', $v, 0, PREG_SPLIT_NO_EMPTY);
// or return preg_split('/(?=[e-g])/', $v, 0, PREG_SPLIT_NO_EMPTY);
},
preg_match_all('/(?:[e-g]\d+)+(?=c)/', $string, $out1) ? $out1[0] : [] // split into groups using c
// or explode('c', rtrim($string, 'c'))
// or array_slice(explode('c', $string), 0, -1)
// or preg_split('/c/', $string, 0, PREG_SPLIT_NO_EMPTY)
)
);
echo"\n\n";
}
Output:
array (
0 =>
array (
0 => 'e123',
1 => 'f654',
2 => 'g933',
),
)
array (
0 =>
array (
0 => 'e123',
1 => 'f654',
2 => 'g933',
),
1 =>
array (
0 => 'e99',
1 => 'f77',
2 => 'g66',
),
)
It seems you are looking for
[e-g]\d+
This needs to be matched and extracted in PHP like so...
<?php
$strings = ['e123f654g933c', 'e123f654g933ce99f77g66c'];
$regex = '~[e-g]\d+~';
foreach ($strings as $string) {
if (preg_match_all($regex, $string, $matches)) {
print_r($matches[0]);
}
}
?>
... and yields
Array
(
[0] => e123
[1] => f654
[2] => g933
)
Array
(
[0] => e123
[1] => f654
[2] => g933
[3] => e99
[4] => f77
[5] => g66
)
You may use
'~(?:\G(?!^)|(?=(?:[e-g]\d+)+c))[e-g]\d+~'
See the regex demo. In short, due to the (?:\G(?!^)|(?=(?:[e-g]\d+)+c)) part, [e-g]\d+ will only match when in between 1 or more occurrences of [e-g]\d+ and c.
Details
(?:\G(?!^)|(?=(?:[e-g]\d+)+c)) - match the end of the last successful match (\G(?!^)) or (|) the location followed with an e, f or g letter followed with 1+ digits, 1+ occurrences (due to the(?=(?:[e-g]\d+)+c) positive lookahead)
[e-g]\d+ - an e, f or g letter followed with 1+ digits
PHP demo:
$re = '/(?:\G(?!^)|(?=(?:[e-g]\d+)+c))[e-g]\d+/';
$str = 'e123f654g933c and e123f654g933ce99f77g66c';
preg_match_all($re, $str, $matches);
print_r($matches[0]);
// => Array ( [0] => e123 [1] => f654 [2] => g933 [3] => e123 [4] => f654 [5] => g933 [6] => e99 [7] => f77 [8] => g66 )
You can't easily achieve this with a single RegExp.
The solution is to split the string at the occurrences of 'c', handle the parts separately, and then build the result array:
<?php
$strings = [
'e123f654g933c',
'e123f654g933ce99f77g66c',
];
foreach ($strings as $input)
{
print_r(match($input));
}
function match($input)
{
$result = [];
$parts = array_filter(explode('c', $input));
foreach ($parts as $part)
{
preg_match_all('~[e-g]\d+~', $part, $matches);
$result[] = $matches[0];
}
return $result;
}
The output will be
Array
(
[0] => Array
(
[0] => e123
[1] => f654
[2] => g933
)
)
Array
(
[0] => Array
(
[0] => e123
[1] => f654
[2] => g933
)
[1] => Array
(
[0] => e99
[1] => f77
[2] => g66
)
)

Wrong working regular expression for parsing short terms

I wrote some a regular expression for PHP to parsing abbreviation from string.
My code:
$re = "/(([$]?+[А-Яа-я.]+[.]){1,})/";
$str = "г. Братск, ж.р. Южный Падун, ул. Мамырская, 62А, за остановкой";
preg_match_all($re, $str, $matches);
And this script return:
Array
(
[0] => Array
(
[0] => г.
[1] => ж.
[2] => л.
)
[1] => Array
(
[0] => г.
[1] => ж.
[2] => л.
)
[2] => Array
(
[0] => г.
[1] => ж.
[2] => л.
)
)
But it will work like this:
[1]=>'ж.р.', [2]=>'ул.'
It means, that my regex parse part of abbreviation, though I need to get full abbreviation.
For example on regex101.com it pretty works: https://regex101.com/r/wQ7lR7/1
How I can get full abbreviation ('г.','ж.р.','ул.')?
You need to use the unicode modifier, u, http://php.net/manual/en/reference.pcre.pattern.modifiers.php.
Example:
$re = "/(([$]?+[А-Яа-я.]+[.]){1,})/u";
$str = "г. Братск, ж.р. Южный Падун, ул. Мамырская, 62А, за остановкой";
preg_match_all($re, $str, $matches);
print_r($matches);
Output:
Array
(
[0] => Array
(
[0] => г.
[1] => ж.р.
[2] => ул.
)
[1] => Array
(
[0] => г.
[1] => ж.р.
[2] => ул.
)
[2] => Array
(
[0] => г.
[1] => ж.р.
[2] => ул.
)
)

preg_match_all and umlets

I am using preg_match_all to filter out strings
The string which I have supplied in preg_match_all is
$text = "Friedric'h Wöhler"
after that I use
preg_match_all('/(\"[^"]+\"|[\\p{L}\\p{N}\\*\\-\\.\\?]+)/', $text, $arr, PREG_PATTERN_ORDER);
and the result i get when I print $arr is
Array
(
[0] => Array
(
[0] => friedric
[1] => h
[2] => w
[3] => ouml
[4] => hler
)
[1] => Array
(
[0] => friedric
[1] => h
[2] => w
[3] => ouml
[4] => hler
)
)
Somehow the ö character is replaced by ouml which I am not really sure how to figure this out
I am expecting following result
Array
(
[0] => Array
(
[0] => Friedric'h
[1] => Wöhler
)
)
Per nhahtdh's comment:
$text = "Friedric'h Wöhler";
preg_match_all('/"[^"]+"|[\p{L}\p{N}*.?\\\'-]+/u', $text, $arr, PREG_PATTERN_ORDER);
echo "<pre>";
print_r($arr);
echo "</pre>";
Gives
Array
(
[0] => Array
(
[0] => Friedric'h
[1] => Wöhler
)
)
If you think preg_match_all() is messy, you could take a look at pattern():
$p = '"[^"]+"|[\p{L}\p{N}*.?\\\'-]+'; // automatic delimiters
$text = "Friedric'h Wöhler";
$result = pattern($p)->match($text)->all();

Regular expression help in PHP

I have a block of text where I need yo find bits of text like:
{slider:1}
{video-alt:10}
I have this bit of code
$regex = '/{[ ]*(slider)|(slider-alt)|(video)[ ]*:[0-9]+[ ]*}/';
$matches = array();
preg_match_all( $regex, $row->content, $matches );
But the array returned is all messed up...
Array output:
Array ( [0] => {slider [1] => {slider [2] => video:2} )
Array ( [0] => slider [1] => slider [2] => )
Array ( [0] => [1] => [2] => )
Array ( [0] => [1] => [2] => video )
For the input:
{slider:6}
{slider-alt:2}
{video:2}
Any help?
Your regexp is messy.
$regex = '/{ *(slider|slider-alt|video) *:\d+ *}/';
$matches = array();
preg_match_all( $regex, $row->content, $matches );

Multiple matches of the same type in preg_match

I want to use preg_match to return an array of every match for parenthesized subpattern.
I have this code:
$input = '[one][two][three]';
if ( preg_match('/(\[[a-z0-9]+\])+/i', $input, $matches) )
{
print_r($matches);
}
This prints:
Array ( [0] => [one][two][three], [1] => [three] )
... only returning the full string and the last match. I would like it to return:
Array ( [0] => [one][two][three], [1] => [one], [2] => [two], [3] => [three] )
Can this be done with preg_match?
Use preg_match_all() with the + dropped.
$input = '[one][two][three]';
if (preg_match_all('/(\[[a-z0-9]+\])/i', $input, $matches)) {
print_r($matches);
}
Gives:
Array
(
[0] => Array
(
[0] => [one]
[1] => [two]
[2] => [three]
),
[1] => Array
(
[0] => [one]
[1] => [two]
[2] => [three]
)
)
$input = '[one][two][three]';
if ( preg_match_all('/(\[[a-z0-9]+\])+/iU', $input, $matches) )
{
print_r($matches);
}

Categories