Sscanf with regex to match even an empty string - php

I am using this regex in sscanf
sscanf($seat, "%d-%[^(](%[^#]#%[^)])");
And it works well when i'm getting this kind of strings:
173-9B(AA#3.45 EUR#32H)
but when i'm getting this kind of string:
173-9B(#3.14 EUR#32H)
it's all messed up, how can I also accept empty strings between the first ( and the first # ?

You would be better off using a regex in preg_match to handle optional data presence in input:
$re = '/(\d*)-([^(]*)\(([^#]*)#([^)]*)\)/';
preg_match($re, '173-9B(#3.45 EUR#32H)', $m);
unset($m[0]);
print_r($m);
Output:
Array
(
[1] => 173
[2] => 9B
[3] =>
[4] => 3.45 EUR#32H
)
And 2nd example:
preg_match($re, '173-9B(AA#3.45 EUR#32H)', $m);
unset($m[0]);
print_r($m);
Array
(
[1] => 173
[2] => 9B
[3] => AA
[4] => 3.45 EUR#32H
)
Use of ([^#]*) will make it match 0 more characters that are not #.

Related

regex split a string between [ and ]

My string is something like that '[15][18][22]' and now I like so split it into an array of [15] and [18] and [22]. I'm trying with this regex
\[\d+\]
But it only split the first one.
thanks for help
You are better off using preg_match_all with what you want to capture:
if (preg_match_all('/\[\d+]/', $str, $m)) {
print_r($m[0]);
}
Output:
Array
(
[0] => [15]
[1] => [18]
[2] => [22]
)
Or else you may use this preg_split with a capture group:
$str = '[15][18][22]';
$arr = preg_split('/(\[\d+])/', $str, -1,
PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
print_r($arr);
Output:
Array
(
[0] => [15]
[1] => [18]
[2] => [22]
)
It just doesn't get any simpler than this. Three characters in the pattern. You only need to explode on the zero-width position after each ]. \K tells the regex engine to forget/release the previously matched character.
~]\K~ Pattern Demo
Code: (Demo)
$string = '[15][18][22]';
var_export(preg_split('~]\K~', $string, -1, PREG_SPLIT_NO_EMPTY));
Output:
array (
0 => '[15]',
1 => '[18]',
2 => '[22]',
)
This will perform with maximum efficiency because it doesn't have any capture groups, lookarounds, or alternatives to slow it down.

Whitespace delimiter not being captured in preg split

<?php
$text = "Testing text splitting\nWith a newline!";
$textArray = preg_split('/\s+/', $text, 0, PREG_SPLIT_DELIM_CAPTURE);
print_r($textArray);
The above code will output the following:
Array
(
[0] => Testing
[1] => text
[2] => splitting
[3] => With
[4] => a
[5] => newline!
)
However to my knowledge the PREG_SPLIT_DELIM_CAPTURE flag should be capturing the whitespace delimiters in the array. Am I missing something?
edit: Ok, after rereading the documentation I now understand PREG_SPLIT_DELIM_CAPTURE is not meant for this case. My desired output would be something like:
Array
(
[0] => Testing
[1] => ' '
[2] => text
[3] => ' '
[4] => splitting
[5] => '\n'
[6] => With
[7] => ' '
[8] => a
[9] => ' '
[10] => newline!
)
So if you read manual for PREG_SPLIT_DELIM_CAPTURE once again which says:
If this flag is set, parenthesized expression in the delimiter pattern will be captured and returned as well.
you will suddenly understand that expression in the delimiter pattern (in your case it is \s) will be captured (i.e added to result) only when it is in parentheses. Now, you can:
$text = "Testing text splitting\nWith a newline!";
$textArray = preg_split('/(\s+)/', $text, 0, PREG_SPLIT_DELIM_CAPTURE);
// parentheses!
print_r($textArray);
You can also use T-Regx library:
$textArray = pattern('(\s+)')->split("Testing text splitting\nWith a newline!")->inc();

how to split a string containing numbers in our outside parenthesis using preg_match_all

I have a string that looks something like this:
535354 345356 3543674 34667 2345347 -3536 4532452 (234536 2345634 -4513453) (2345 -13254 13545)
The text between () is always at the end of the string (at least for now).
i need to split it into an array similar to this:
[0] => [0] 535354,345356,3543674,34667,2345347,-3536,4532452
[1] => [0] 234536,2345634,-4513453
=> [1] 2345,-13254,13545
What expression should i use for preg_match_all?
Best i could get with my limited knowledge is /([0-9]{1,}){1,}.*(?=(\(.*\)))/U but i still get some unwanted elements.
You may use a regex that will match chunks of numbers outside of parentheses and those inside with "~(?<=\()\s*$numrx\s*(?=\))|\s*$numrx~" where a $numrx stands for the number regex (that can be enhanced further).
The -?\d+(?:\s+-?\d+)* matches an optional -, 1 or more digits, and then 0+ sequences of 1+ whitespaces followed with optional - and 1+ digits. (?<=\()\s*$numrx\s*(?=\)) matches the same only if preceded with ( and followed with ).
See this PHP snippet:
$s = "535354 345356 3543674 34667 2345347 -3536 4532452 (234536 2345634 -4513453) (2345 -13254 13545)";
$numrx = "-?\d+(?:\s+-?\d+)*";
preg_match_all("~(?<=\()\s*$numrx\s*(?=\))|\s*$numrx~", $s, $m);
$res = array();
foreach ($m[0] as $k) {
array_push($res,explode(" ",trim($k)));
}
print_r($res);
Output:
[0] => Array
(
[0] => 535354
[1] => 345356
[2] => 3543674
[3] => 34667
[4] => 2345347
[5] => -3536
[6] => 4532452
)
[1] => Array
(
[0] => 234536
[1] => 2345634
[2] => -4513453
)
[2] => Array
(
[0] => 2345
[1] => -13254
[2] => 13545
)
You can use this regex in preg_match_all:
$re = '/\d+(?=[^()]*[()])/';
RegEx Demo
RegEx Breakup:
\d+ # match 1 or more digits
(?= # lookahead start
[^()]* # match anything but ( or )
[()] # match ( or )
) # lookahead end

Regex, get multiple occurrences

I would like to know how to get multiple occurrences from a regex.
$str = "Some validations <IF TEST>firstValue</IF> in <IF OK>secondValue</IF> end of string.";
$do = preg_match("/<IF(.*)>.*<\/IF>/i", $str, $matches);
This is what I've done so far. It works if I have only 1 , but if I have more it doesn't return the right values. Here is the result:
Array ( [0] => firstValue in secondValue [1] => TEST>firstValue in
I need to get the "TEST" and the "OK" values.
EDIT: I've brought the modifications suggested, thanks a lot it works fine ! However, I am now trying to add a elsif parameter and can't get it to work well. Here is what I've done:
$do = preg_match_all("~<IF([^<>]+)>([^<>]+)(</IF>|<ELSEIF([^<>]+)>([^<>]+)</IF>)~", $str, $matches, PREG_SET_ORDER);
and the results is
Array
(
[0] => Array
(
[0] => firstValuesecondValue
[1] => TEST
[2] => firstValue
[3] => secondValue
[4] => TEST1
[5] => secondValue
)
[1] => Array
(
[0] => thirdValue
[1] => OK
[2] => thirdValue
[3] =>
)
)
Is there a way to make my array more clean ? It has many elements which are useless like the [0][4] etc.
You should make the regex more specific. The .* that you are using should either be less greedy, or better yet disallow other angle brackets:
~<IF([^<>]+)>([^<>]+)</IF>~i
More importantly, you should use preg_match_all, not just preg_match.
preg_match_all("~<IF([^<>]+)>([^<>]+)</IF>~i", $str, $matches, PREG_SET_ORDER);
That'll give you a nested array like:
[0] => Array
(
[0] => <IF TEST>firstValue</IF>
[1] => TEST
[2] => firstValue
)
[1] => Array
(
[0] => <IF OK>secondValue</IF>
[1] => OK
[2] => secondValue
)
The answers pointing out that you should use preg_match_all are correct.
But there is another problem: the .* is greedy by default. This will cause it to match both tags in a single match, so you need to make the star non-greedy (i.e. lazy):
/<IF(.*?)>.*?<\/IF>/i
Use this code:
$string = "Some validations <IF TEST>firstValue</IF> in <IF OK>secondValue</IF> end of string.";
$regex = "/<IF (.*?)>.*?<\/IF>/i";
preg_match_all($regex, $string, $matches);
print_r($matches[1]);
You regex is good but you have to use the non-greedy mode adding the ? char and use the preg_match_all() function.
Use a non-greedy match .*? and preg_match_all for this purpose.

php regex split string by [%%%]

Hi I need a preg_split regex that will split a string at substrings in square brackets.
This example input:
$string = 'I have a string containing [substrings] in [brackets].';
should provide this array output:
[0]= 'I have a string containing '
[1]= '[substrings]'
[2]= ' in '
[3]= '[brackets]'
[4]= '.'
After reading your revised question:
This might be what you want:
$string = 'I have a string containing [substrings] in [brackets].';
preg_split('/(\[.*?\])/', $string, null, PREG_SPLIT_DELIM_CAPTURE);
You should get:
Array
(
[0] => I have a string containing
[1] => [substrings]
[2] => in
[3] => [brackets]
[4] => .
)
Original answer:
preg_split('/%+/i', 'ot limited to 3 %%% so it can be %%%% or % or %%%%%, etc Tha');
You should get:
Array
(
[0] => ot limited to 3
[1] => so it can be
[2] => or
[3] => or
[4] => , etc Tha
)
Or if you want a mimimum of 3 then try:
preg_split('/%%%+/i', 'Not limited to 3 %%% so it can be %%%% or % or %%%%%, etc Tha');
Have a go at http://regex.larsolavtorvik.com/
I think this is what you are looking for:
$array = preg_split('/(\[.*?\])/', $string, null, PREG_SPLIT_DELIM_CAPTURE);

Categories