preg_match confuses me so I apologise if this is a simple question or been asked before but I can't make sense of answer to know if its what I need.
I have a string that follows this format: Test 1#1.00 Test 2#2.00 Test 3#3.00
I then use this pattern to seperate the values
/(?P<first>([^**]*?))#(?P<second>\d{0,7}(?:\.\d{1,2}))/
So end up with
Array ( [0] => Test 1 [1] => Test 2 [2] => Test 3 )
Array ( [0] => 1.00 [1] => 2.00 [2] => 3.00 )
Where I'm struggling is changing the pattern to find a decimal like it currently does or the word/letters FOC or TBC
So my string will be for example: Test 1#1.00 Test 2#FOC Test 3#3.00
and my arrays will be:
Array ( [0] => Test 1 [1] => Test 2 [2] => Test 3 )
Array ( [0] => 1.00 [1] => FOC [2] => 3.00 )
Currently, my pattern won't work with FOC and will just return the first in each array.
Any help greatly appreciated.
My suggestion is to add a \w+
alternative before the regex engine tries to match a number:
(?P<first>[^#]*)#(?P<second>\d{0,7}\.\d{1,2}|\w+)
Or, to start matching keys with the first non-whitespace char (demo):
(?P<first>[^#\s][^#]*)#(?P<second>\d{0,7}\.\d{1,2}|\w+)
^^^^^^
See the regex demo.
Details
(?P<first>[^#]*)
- Group "first" matching 0+ chars other than #
(it is a negated character class here due to ^
being the first char after [
)#
- a #
symbol(?P<second>\d{0,7}\.\d{1,2}|\w+)
- Group "second" that matches
\d{0,7}\.\d{1,2}
- 0 to 7 digits followed with .
and then 1 or 2 digits|
- or\w+
- 1+ word chars (letters, digits or _
)See the PHP demo:
$re = '/(?P<first>[^#]*)#(?P<second>(?:\d{0,7}\.\d{1,2}|\w+))/';
$str = 'Test 1#1.00 Test 2#2.00 Test 3#3.00
Test 1#1.00 Test 2#FOC Test 3#3.00';
preg_match_all($re, $str, $matches);
print_r($matches["first"]);
echo "\n";
print_r($matches["second"]);