Skip to content

PHP: Split a string at the first period that isn’t the decimal point in a price or the last character of the string

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).


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"



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.
User contributions licensed under: CC BY-SA
10 People found this is helpful