I want to split a string as per the parameters laid out in the title. I’ve tried a few different things including using preg_match with not much success so far and I feel like there may be a simpler solution that I haven’t clocked on to.
I have a regex that matches the “price” mentioned in the title (see below).
/(?=.)£(([1-9][0-9]{0,2}(,[0-9]{3})*)|[0-9]+)?(.[0-9]{1,2})?/
And here are a few example scenarios and what my desired outcome would be:
Example 1:
input: "This string should not split as the only periods that appear are here £19.99 and also at the end." output: n/a
Example 2:
input: "This string should split right here. As the period is not part of a price or at the end of the string." output: "This string should split right here"
Example 3:
input: "There is a price in this string £19.99, but it should only split at this point. As I want it to ignore periods in a price" output: "There is a price in this string £19.99, but it should only split at this point"
Advertisement
Answer
I suggest using
preg_split('~£(?:[1-9]d{0,2}(?:,d{3})*|[0-9]+)?(?:.d{1,2})?(*SKIP)(*F)|.(?!s*$)~u', $string)
See the regex demo.
The pattern matches your pattern, £(?:[1-9]d{0,2}(?:,d{3})*|[0-9]+)?(?:.d{1,2})?
and skips it with (*SKIP)(*F)
, else, it matches a non-final .
with .(?!s*$)
(even if there is trailing whitespace chars).
If you really only need to split on the first occurrence of the qualifying dot you can use a matching approach:
preg_match('~^((?:£(?:[1-9]d{0,2}(?:,d{3})*|[0-9]+)?(?:.d{1,2})?|[^.])+).(.*)~su', $string, $match)
See the regex demo. Here,
^
– matches a string start position((?:£(?:[1-9]d{0,2}(?:,d{3})*|[0-9]+)?(?:.d{1,2})?|[^.])+)
– one or more occurrences of your currency pattern or any one char other than a.
char.
– a.
char(.*)
– Group 2: the rest of the string.