Regex PHP only gets the first match - php

I have an string which looks like:
aaaaaaaa'bbbbbbbb?'cccccccccccc'ddddddddd'
I would like to get all the matches separate by ' but not the ones escaped with ?'
I managed to do it by using this expression:
(.*?)[^\\?]'
And I tested it on regexpal and seems to work properly.
When trying to apply it to my PHP code by using preg_match I only get the first match.
This is my code:
preg_match ("/(.*?)[^\\?]'/i", $content, $matches);
print_r($matches);
And the result is:
Array
(
[0] => aaaaaaaaaaaaaaaa'
[1] => aaaaaaaaaaaaaaa
)
I'm expecting to get bbbbbbbb?'cccccccccccc' and ddddddddd' as well.
What am I doing wrong? Thanks.

You can use this negative lookbehind regex in preg_match_all:
$s = "aaaaaaaa'bbbbbbbb?'cccccccccccc'ddddddddd'";
if (preg_match_all("/(.*?)(?<!\?)'/", $s , $m ))
print_r($m[1]);
OR using preg_split:
$arr = preg_split("/(?<!\?)'/", $s, -1, PREG_SPLIT_NO_EMPTY);
OUTPUT
Array
(
[0] => aaaaaaaa
[1] => bbbbbbbb?'cccccccccccc
[2] => ddddddddd
)

use preg_match_all() to get all matches instead of one
$content = "aaaaaaaa'bbbbbbbb?'cccccccccccc'ddddddddd'";
preg_match_all("/(.*?)[^\\?]'/i", $content, $matches);
print_r($matches);
result
Array (
[0] =>
Array (
[0] => aaaaaaaa'
[1] => bbbbbbbb?'cccccccccccc'
[2] => ddddddddd'
)
[1] =>
Array (
[0] => aaaaaaa
[1] => bbbbbbbb?'ccccccccccc
[2] => dddddddd
)
)

Simply You can try this
$s = "aaaaaaaa'bbbbbbbb?'cccccccccccc'ddddddddd'";
$arr = preg_split("/[^?]'/", $s, -1, PREG_SPLIT_NO_EMPTY);
Out Put Array
Array
(
[0] => aaaaaaa
[1] => bbbbbbbb?'ccccccccccc
[2] => dddddddd
)

Related

How to extract certain words from a php string?

I have a long string like this I1:1;I2:2;I8:2;NA1:5;IA1:[1,2,3,4,5];S1:asadada;SA1:[1,2,3,4,5];SA1:[1,2,3,4,5];. Now I just want to get certain words like 'I1','I2','I8','NA1' and so on i.e. words between ':'&';' only ,and store them in array. How to do that efficiently?
I have already tried using preg_split() and it works but giving me wrong output. As shown below.
// $a is the string I want to extract words from
$str = preg_split("/[;:]/", $a);
print_r($str);
The output I am getting is this
Array
(
[0] => I8
[1] => 2
[2] => I1
[3] => 1
[4] => I2
[5] => 2
[6] => I3
[7] => 2
[8] => I4
[9] => 4
[10] =>
)
Array
(
[0] => NA1
[1] => 5
[2] =>
)
Array
(
[0] => IA1
[1] => [1,2,3,4,5]
[2] =>
)
Array
(
[0] => S1
[1] => asadada
[2] =>
)
Array
(
[0] => SA1
[1] => [1,2,3,4,5]
[2] =>
)
But I am expecting 'I8','I1','I2','I3','I4' also in seperated array with position [0]. Any help on how to do this.
You could try something like.
<?php
$str = 'I1:1;I2:2;I8:2;NA1:5;IA1:[1,2,3,4,5];S1:asadada;SA1:[1,2,3,4,5];SA1:[1,2,3,4,5];';
preg_match_all('/(?:^|[;:])(\w+)/', $str, $result);
print_r($result[1]); // Matches are here in $result[1]
You can perform a greedy match to match the items between ; and : using preg_match_all()
<?php
$str = 'I1:1;I2:2;I8:2;NA1:5;IA1:[1,2,3,4,5];S1:asadada;SA1:[1,2,3,4,5];SA1:[1,2,3,4,5];';
preg_match_all('/;(.+?)\:/',$str,$matches);
print_r($matches[1]);
Live Demo: https://3v4l.org/eBsod
One possible approach is using a combination of explode() and implode(). The result is returned as a string, but you can easily put it into an array for example.
<?php
$input = "I1:1;I2:2;I8:2;NA1:5;IA1:[1,2,3,4,5];S1:asadada;SA1:[1,2,3,4,5];SA1:[1,2,3,4,5];.";
$output = array();
$array = explode(";", $input);
foreach($array as $item) {
$output[] = explode(":", $item)[0];
}
echo implode(",", $output);
?>
Output:
I1,I2,I8,NA1,IA1,S1,SA1,SA1,.

php regex mach before and after specific word

I have a string with data that looks like this:
$string = '
foo=bar
badge_name_foo=foo
bar_badge_name=bar
bar=baz
';
I want to match all *_badge_name and badge_name_* strings.
The regex im using is this:
preg_match_all('~(?:(\w+)_)?badge_name(?:_(\w+))?~', $string, $matches, PREG_SET_ORDER);
The result is:
Array
(
[0] => Array
(
[0] => badge_name_foo
[1] =>
[2] => foo
)
[1] => Array
(
[0] => bar_badge_name
[1] => bar
)
)
The *_badge_name is working fine, but on badge_name_* there is every time a empty value? Now how can i remove that with preg_match_all
Expected result should be:
Array
(
[0] => Array
(
[0] => badge_name_foo
[1] => foo
)
[1] => Array
(
[0] => bar_badge_name
[1] => bar
)
)
It seems you need to use BRANCH RESET feature:
Alternatives inside a branch reset group share the same capturing groups. The syntax is (?|regex) where (?| opens the group and regex is any regular expression. If you don't use any alternation or capturing groups inside the branch reset group, then its special function doesn't come into play. It then acts as a non-capturing group.
Use
(?|(\w+)_badge_name|badge_name_(\w+))
^^^
See the regex demo.
PHP demo:
$re = '/(?|(\w+)_badge_name|badge_name_(\w+))/';
$str = 'foo=bar
badge_name_foo=foo
bar_badge_name=bar
bar=baz';
preg_match_all($re, $str, $matches);
print_r($matches);
Result:
Array
(
[0] => Array
(
[0] => badge_name_foo
[1] => bar_badge_name
)
[1] => Array
(
[0] => foo
[1] => bar
)
)

To explode the string based on the special characters in Php

I have a string:
xyz.com?username="test"&pwd="test"#score="score"#key="1234"
output format:
array (
[0] => username="test"
[1] => pwd="test"
[2] => score="score"
[3] => key="1234"
)
This should work for you:
Just use preg_split() with a character class with all delimiters in it. At the end just use array_shift() to remove the first element.
<?php
$str = 'xyz.com?username="test"&pwd="test"#score="score"#key="1234"';
$arr = preg_split("/[?&##]/", $str);
array_shift($arr);
print_r($arr);
?>
output:
Array
(
[0] => username="test"
[1] => pwd="test"
[2] => score="score"
[3] => key="1234"
)
You can use preg_split function with regex pattern including all those delimimting special characters. Then remove the first value of the array and reset keys:
$s = 'xyz.com?username="test"&pwd="test"#score="score"#key="1234"';
$a = preg_split('/[?&##]/',$s);
unset($a[0]);
$a = array_values($a);
print_r($a);
Output:
Array (
[0] => username="test"
[1] => pwd="test"
[2] => score="score"
[3] => key="1234"
)

Preg_match_all behaving wierd

I am new to PHP and I have the below code and I basically wish to find all keywords enclosed between
'<#' and '#>'
sample code:
<?php
$subject = "askdbvbaldjbvasdblasdbvl<#2134#>cbkdbskbkabdvb<#213aca4#>";
$pattern = "/(?<=\<\#)(.*?)(?=\#\>)/";
preg_match_all($pattern, $subject, $matches);
echo '<pre>',print_r($matches,true),'</pre>';
?>
now i am expecting a value array like:
Array
(
[0] => Array
(
[0] => 2134
[1] => 213aca4
)
)
But i am getting and output like:
Array
(
[0] => Array
(
[0] => 2134
[1] => 213aca4
)
[1] => Array
(
[0] => 2134
[1] => 213aca4
)
)
can any one tell me why am i getting the second array and how can i get rid of that..
The second array contains the sub-match, or matched group, because you're using a capture group.
Simply remove the parens in your regex:
$pattern = "/(?<=\<\#).*?(?=\#\>)/";
Also, you should be able to use this regex without some escapes:
$pattern = "/(?<=<#).*?(?=#>)/";

php returned array from preg_match_all

i have an array that is being returned like this:
Array ( [0] => Array ( [0] => ;3750;011; [1] => ;3750;012; [2] => ;3750;013; [3] => ;3750;014; [4] => ;3750;015; [5] => ;3750;016; [6] => ;3750;017; [7] => ;3750;018; [8] => ;3750;019; ))
the array is coming from preg_match_all
I have tried to print it with foreach loop and it always returns the same way
i can't work with it like this.. and i do not understand what is going on
this is the preg_match_all that it comes from:
$remove = preg_match_all('/;([\d]{4};[\d]{3});/', $str, $m);
preg_match_all() returns in match result an array of arrays. Then to display all the whole matches you must use:
$remove = preg_match_all('/;([\d]{4};[\d]{3});/', $str, $m);
foreach($m[0] as $item) { echo $item . '<br/>'; }
If you only want the content of your capturing group, just replace $m[0] by $m[1]

Categories