Get Repeated Matches with Preg_Match_All()

Get repeated matches with preg_match_all()

According to Kobi (see comments above):

PHP has no support for captures of the same group

Therefore this question has no solution.

repeated pattern in preg_match_all pattern doesn't result in multiple $matches

PCRE stores the last occurrence in a repeating capturing group so the behavior is expected. To return individual matches in this case, you need to work with \G token as the following:

(?:^mem:|\G(?!^))\s+\K\d+

See live demo

Regex breakdown:

  • (?: Start of non-capturing group

    • ^mem: Match mem: at beginning of input string
    • | Or
    • \G(?!^) Start match from where previous match ends
  • ) End of non-capturing group
  • \s+\K Match any sequence of whitespaces then clear output
  • \d+ Match digits

PHP code:

preg_match_all("~(?:^mem:|\G(?!^))\s+\K\d+~", $str, $matches);

PHP preg_match to find multiple occurrences

You want to use preg_match_all(). Here is how it would look in your code. The actual function returns the count of items found, but the $matches array will hold the results:

<?php
$string = "/brown fox jumped [0-9]/";

$paragraph = "The brown fox jumped 1 time over the fence. The green fox did not. Then the brown fox jumped 2 times over the fence";

if (preg_match_all($string, $paragraph, $matches)) {
echo count($matches[0]) . " matches found";
}else {
echo "match NOT found";
}
?>

Will output:

2 matches found

Get multiple values from preg_match_all and use of foreach

You can do that if you change the order in which the matches are returned. Use PREG_SET_ORDER and you will get them in a format that can be more easily iterated.

preg_match_all('/\[img alt=(.*?)\](.+?)\[\/img\]/i', $artikel, $matches, PREG_SET_ORDER);

foreach ($matches as $match){
//example code
$stmt = $conn->prepare("INSERT INTO images (img_file, img_alt_text) VALUES (?, ?)");
$stmt->bind_param("ss", $img_file, $img_alt_text);

$img_alt_text = $match[1];
$img_file = $match[2];
$stmt->execute();
}

php preg_match_all need multiple results

Here is an alternate solution using preg_replace_callback to do the job.

  • Look for strings matching "any characters followed by (and including) three 'a' characters, some space and five digits". There may be trailing spaces. The \b denotes a word boundary, preventing matches on "xaaa 12345", "aaa 123456" or "aaa 12345xyz"
  • Concatenate the matching string to $soFar, which contains any previously matched strings
  • Append that string to the $result array

I am not quite sure whether you wanted the "foo"s and "bar"s to remain in the string so I just left them in.

$str = "whatever foo aaa 12345 bar aaa 34567 aaa 56789 baz fez";

preg_replace_callback(
'/.*?\baaa +\d{5}\b\s*/',
function ($matches) use (&$result, &$soFar) {
$soFar .= $matches[0];
$result[] = trim($soFar);
}, $str
);
print_r($result);

Output:

Array
(
[0] => whatever foo aaa 12345
[1] => whatever foo aaa 12345 bar aaa 34567
[2] => whatever foo aaa 12345 bar aaa 34567 aaa 56789
)

Two-step version using preg_match_all and array_map:

preg_match_all('/.*?\baaa +\d{5}\b\s*/', $str, $matches);
$matches = array_map(
function ($match) use (&$soFar) {
$soFar .= $match;
return trim($soFar);
},
$matches[0]
);
print_r($matches);

Regex: Match all duplicate characters PHP

You can convert the string to an array:

$string = "aecffead";
var_export(array_keys(array_intersect(array_count_values(str_split($string)),[1])));

Output:

array (
0 => 'c',
1 => 'd',
)

This gets the value counts as an array, then uses array_intersect() to only retain values that occur once, then turns the keys into the values of a zero-index array.

Additionally you can convert the array back to a string using implode()

Example: https://eval.in/820930


Edit: alternatively you can try this (using your regex-pattern):

$string = "aecffead";

preg_match_all('/([a-z])(?=.*\1)/', $string, $matches);

echo str_replace($matches[0], "", $string); //Output: cd

Example: https://eval.in/820969

Multiple matches of the same type in 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]
)
)


Related Topics



Leave a reply



Submit