Multiline PHP Regex problem - php

I already tried looking here and in google... but I can't figure out what am I doing wrong :(
I have this text:
C 1 title
comment 1
C 2 title2
comment 2
C 3 title3
comment 3
Now... What I want to do is
Check for the C at the beggining.
Capture the number
Capture the Tile
Capture the comment
I'm trying to use this expression:
preg_match_all("/^C (\d*) (.*)\n(.*)$/im", $body, $match);
but it only works for the first set =(
Any tip on what am I doing wrong???
Thanks!!!!

It works as expected.
The snippet:
<?php
$body = 'C 1 title
comment 1
C 2 title2
comment 2
C 3 title3
comment 3';
preg_match_all("/^C (\d*) (.*)\n(.*)$/im", $body, $match);
print_r($match);
?>
produces the following output:
Array
(
[0] => Array
(
[0] => C 1 title
comment 1
[1] => C 2 title2
comment 2
[2] => C 3 title3
comment 3
)
[1] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
[2] => Array
(
[0] => title
[1] => title2
[2] => title3
)
[3] => Array
(
[0] => comment 1
[1] => comment 2
[2] => comment 3
)
)
as you can see on Ideone.
To keep your matches nicely grouped, you might want to try:
preg_match_all("/^C (\d*) (.*)\n(.*)$/im", $body, $match, PREG_SET_ORDER);
instead.
HTH
EDIT
Ideone runs: PHP Version => 5.2.12-pl0-gentoo
And I also tested it on my machine (and get the same result), which runs: PHP Version => 5.3.3-1ubuntu9.5
But I can't imagine this is a versioning thing (at least, not with 5.x versions). Perhaps your line breaks are Windows style? Try this regex instead:
"/^C +(\d*) +(.*)\r?\n(.*)$/im"
I used the line break \r?\n instead of just \n so that Windows and Unix-style line breaks are matched, and also replaced single spaces with + to account for possible two (or more) spaces.

Related

php split / cluster binary into chunks based on next 1 in cycle

I need to figure out a method using PHP to chunk the 1's and 0's into sections.
1001 would look like: array(100,1)
1001110110010011 would look like: array(100,1,1,10,1,100,100,1,1)
It gets different when the sequence starts with 0's... I would like it to segment the first 0's into their own blocks until the first 1 is reached)
00110110 would look like (0,0,1,10,1,10)
How would this be done with PHP?
You can use preg_match_all to split your string, using the following regex:
10*|0
This matches either a 1 followed by some number of 0s, or a 0. Since a regex always tries to match the parts of an alternation in the order they occur, the second part will only match 0s that are not preceded by a 1, that is those at the start of the string. PHP usage:
$beatstr = '1001110110010011';
preg_match_all('/10*|0/', $beatstr, $m);
print_r($m);
$beatstr = '00110110';
preg_match_all('/10*|0/', $beatstr, $m);
print_r($m);
Output:
Array
(
[0] => Array
(
[0] => 100
[1] => 1
[2] => 1
[3] => 10
[4] => 1
[5] => 100
[6] => 100
[7] => 1
[8] => 1
)
)
Array
(
[0] => Array
(
[0] => 0
[1] => 0
[2] => 1
[3] => 10
[4] => 1
[5] => 10
)
)
Demo on 3v4l.org

Regex pattern + preg_split keep delimiter [duplicate]

This question already has an answer here:
PHP preg_split while keeping delimiter at the start of array element
(1 answer)
Closed 3 years ago.
I read posts about regex and preg_split but nothing fitting to my interests.
I have the following text:
C01G01 Jon Doe Kenny Ranny C02G02 Ramsay John C02G03 Alice Axel
I want to use preg_split where the delimiter is C(number)G(number) and also keep the delimiter in the array.
What I have done:
$parts = preg_split('/C+[0-200]+G+[0-200]/',
$students,-1,PREG_SPLIT_DELIM_CAPTURE);
What Is returning:
Array(
[0] =>
[1] => 1 Jon Doe Kenny Ranny
[2] => 2 Ramsay John
[3] => 3 Alice Axel
)
What I expect to return:
Array(
[0] =>
[1] => C01G01 Jon Doe Kenny Ranny
[2] => C02G02 Ramsay John
[3] => C02G03 Alice Axel
)
\s(?=C+\d+G+\d+)
You can use something of this sort.See demo.
https://regex101.com/r/qyCwCN/1

Finding (regex?) 10 digits in a row (PHP)

I am facing a problem i am not capable to solve. I have a string consisting of not needed text and 10 digit numbers who always start with "2" or "6". I need to get those in 10digit numbers into an array. I thought of regex and found this article Regular Expression for matching a numeric sequence? which is pretty close to what i need (except the descending/ascending thing) yet, as i could never and will NEVER be able to understand regex, i cant modify to my needs. If anyone could help me out here i would highly appreciate it!
Here is a sample of my string:
".........693 7098469 - ZQH X Bop. Hrtepou 50 flerpoUrroXn ........210 5014166 - 0E000PA E KapaoAn Anpn-rPou 21
EAArivtg .....................................................210 9618677 - MAPIA KapaoAri Arpn-rptou 21 Elanvolo .. 210 9643623 - MAPIA E ...................................................... 210 9643887 - MAPIA 0 loucrrivou 8 HX.toOrran ..............210 9914534 AIPITAKHE APTEMIOE n Avrtnopou 22
Reptcrrept ....._.........._......._................697 7440896 , -10AN."
Thank you very much in advance!
Greetings from Greece!
As I see your string your digits have an space between, and if you want strictly make your selections this is the regex:
[62]\d{2}\s*\d{7}
Explanation:
[62] # Start with 6 or 2
\d{2} # 2 more digits
\s* # any number of white spaces
\d{7} # 7 more digits
Live demo
and PHP code which has preg_match_all to match all occurrences of those strings:
preg_match_all("/[62]\d{2}\s*\d{7}/", $text, $matches);
Output:
Array
(
[0] => 693 7098469
[1] => 210 5014166
[2] => 210 9618677
[3] => 210 9643623
[4] => 210 9643887
[5] => 210 9914534
[6] => 697 7440896
)
PHP live demo
Maybe like this:
<?php
$x=
".........693 7098469 - ZQH X Bop. Hrtepou 50 flerpoUrroXn ........210 5014166 - 0E000PA E KapaoAn Anpn-rPou 21 EAArivtg ....................................................210 9618677 - MAPIA KapaoAri Arpn-rptou 21 Elanvolo .. 210 9643623 - MAPIA E ...................................................... 210 9643887 - MAPIA 0 loucrrivou 8 HX.toOrran ..............210 9914534 AIPITAKHE APTEMIOE n Avrtnopou 22
Reptcrrept ....._.........._......._................697 7440896 , -10AN.";
$x=str_replace(' ','',$x);
preg_match_all('/((2|6)\d{9})/',$x,$matches);
print_r($matches[0]);
And the result:
Array
(
[0] => 6937098469
[1] => 2105014166
[2] => 2109618677
[3] => 2109643623
[4] => 2109643887
[5] => 2109914534
[6] => 6977440896
)
there is a pretty cool page, that visualize the regex code for better understading:
https://www.debuggex.com/
this should work
((?:2|6)[0-9]{2} [0-9]{7})

RegEx Statement Issues - PHP

I am attempting to use RegEx to strip down the following data:
mlb_s_left1=Baltimore 3 ^NY Yankees 12 (FINAL)&mlb_s_right1_1=W: Hughes L: Britton&mlb_s_right1_count=1&mlb_s_url1=http://sports.espn.go.com/mlb/boxscore?gameId=320801110&mlb_s_left2=^Chicago Sox 3 Minnesota 2 (FINAL)&mlb_s_right2_1=W: Peavy L: Diamond S: Reed&mlb_s_right2_count=1&mlb_s_url2=http://sports.espn.go.com/mlb/boxscore?gameId=320801109
I am hoping to split it apart by home team (first city), home score (first digit), away team (second city), away score (second digit), and where in the game it is (in parenthesis). This is the RegEx I have currently, but am feeling is very wrong.
preg_match_all('/mlb_s_left[0-9]=(?P<hometeam>.*?) (?P<homescore>.*?) (?P<awayteam>.*?) (?P<awayscore>.*?)\((?P<time>.*?)\)/', $content, $matches);
I would appreciate any and all help in getting this working.
I have tested following code snippet in php 5.4.5:
<?php
$foo = 'mlb_s_left1=Baltimore 3 ^NY Yankees 12 (FINAL)&mlb_s_right1_1=W: Hughes L: Britton&mlb_s_right1_count=1&mlb_s_url1=http://sports.espn.go.com/mlb/boxscore?gameId=320801110&mlb_s_left2=^Chicago Sox 3 Minnesota 2 (FINAL)&mlb_s_right2_1=W: Peavy L: Diamond S: Reed&mlb_s_right2_count=1&mlb_s_url2=http://sports.espn.go.com/mlb/boxscore?gameId=320801109';
preg_match_all('/mlb_s_left\d=\^?(?P<hometeam>[a-zA-Z]+(?:\s+[a-zA-Z]+)*)\s+(?P<homescore>\d+)\s+\^?(?P<awayteam>[a-zA-Z]+(?:\s+[a-zA-Z]+)*)\s+(?P<awayscore>\d+)\s+\((?P<time>\w+)\)/', $foo, $matches, PREG_SET_ORDER);
print_r($matches);
?>
output:
Array
(
[0] => Array
(
[0] => mlb_s_left1=Baltimore 3 ^NY Yankees 12 (FINAL)
[hometeam] => Baltimore
[1] => Baltimore
[homescore] => 3
[2] => 3
[awayteam] => NY Yankees
[3] => NY Yankees
[awayscore] => 12
[4] => 12
[time] => FINAL
[5] => FINAL
)
[1] => Array
(
[0] => mlb_s_left2=^Chicago Sox 3 Minnesota 2 (FINAL)
[hometeam] => Chicago Sox
[1] => Chicago Sox
[homescore] => 3
[2] => 3
[awayteam] => Minnesota
[3] => Minnesota
[awayscore] => 2
[4] => 2
[time] => FINAL
[5] => FINAL
)
)
Something like this should get you close.
preg_match_all('/mlb_s_left\d+=(?P<hometeam>\D+)\s+(?P<homescore>\d+)\s+(?P<awayteam>\D+)\s+(?P<awayscore>\d+)\s*\((?P<time>[^)]+)\)/',
$content, $matches);
Note that \d matches any digit, and \D matches anything that is not a digit.
[^)]+ matches one or more non-close parens characters; \s+ matches one or more whitespace chars, and \s* matches zero or more whitespace characters.
This wouldn't work very well if you have a city name with a number in it, and if you have a huge string, it's possible it could get hung up somewhere; you might consider splitting it up and matching a bit more piecemeal.
Generally speaking I would avoid .*? as a pattern match, as it basically matches almost anything. It's best for your regular expression to be as specific as possible, based on what you know about the data.

regex match between 2 strings

For example I have the text
a1aabca2aa3adefa4a
I want to extract 2 and 3 with a regex between abc and def, so 1 and 4 should be not included in the result.
I tried this
if(preg_match_all('#abc(?:a(\d)a)+def#is', file_get_contents('test.txt'), $m, PREG_SET_ORDER))
print_r($m);
I get this
> Array
(
[0] => Array
(
[0] => abca1aa2adef
[1] => 3
)
)
But I want this
Array
(
[0] => Array
(
[0] => abca1aa2adef
[1] => 2
[2] => 3
)
)
Is this possible with one preg_match_all call? How can I do it?
Thanks
preg_match_all(
'/\d # match a digit
(?=.*def) # only if followed by <anything> + def
(?!.*abc) # and not followed by <anything> + abc
/x',
$subject, $result, PREG_PATTERN_ORDER);
$result = $result[0];
works on your example. It assumes that there is exactly one instance of abc and def per line in your string.
The reason why your attempt didn't work is that your capturing group (\d) that matches the digit is within another, repeated group (?:a(\d)a)+. With every repetition, the result of the capture is overwritten. This is how regular expressions work.
In other words - see what's happening during the match:
Current position Current part of regex Capturing group 1
--------------------------------------------------------------
a1a no match, advancing... undefined
abc abc undefined
a2a (?:a(\d)a) 2
a3a (?:a(\d)a) (repeated) 3 (overwrites 2)
def def 3
You ask if it is possible with a single preg_match_all.
Indeed it is.
This code outputs exactly what you want.
<?php
$subject='a1aabca2aa3adefa4a';
$pattern='/abc(?:a(\d)a+(\d)a)def/m';
preg_match_all($pattern, $subject, $all_matches,PREG_OFFSET_CAPTURE | PREG_PATTERN_ORDER);
$res[0]=$all_matches[0][0][0];
$res[1]=$all_matches[1][0][0];
$res[2]=$all_matches[2][0][0];
var_dump($res);
?>
Here is the output:
array
0 => string 'abca2aa3adef' (length=12)
1 => string '2' (length=1)
2 => string '3' (length=1)

Categories