OsomA
OsomA

Reputation: 147

Separate float value and date expression from string with no delimiting character

I just started to learn regular expression and I have one example like this 23.0003NOV14DIX. I want to extract 23.00 and 03NOV14DIX.

I tried this:

preg_match("/(?P<a>[0-9]\.[0-9]{2}+)\s+(?P<supplierPrice>)[^\s]\s+/", $line, $matches);

But it is not working. My idea was that extract digits until met character . and then another 2 digits and the rest.

Upvotes: 2

Views: 91

Answers (6)

mickmackusa
mickmackusa

Reputation: 47864

I presume you are performing "text extraction" as opposed to "text validation", but I'll demonstrate both. Demo

If you only need to split the string at the position after the second decimal place, then preg_split() is ideal. \K tells the regex engine to "forget" any previously matched characters -- this ensures that the decimal characters are not consumed as the delimiter between the two halves.

var_export(
    preg_split('/\.\d{2}\K/', $string)
);

If you are trying to validate the whole string AND extract the two parts, then preg_match() is better suited -- but then we might need to see a battery of potential inputs so that we can craft an accurate regex pattern.

var_export(
    preg_match('/^(\d+\.\d{2})((?:\d{2}[A-Z]{3}){2})$/', $string, $m)
    ? array_slice($m, 1)
    : []
);

Both snippets give the same output:

array (
  0 => '23.00',
  1 => '03NOV14DIX',
)

Upvotes: 0

hwnd
hwnd

Reputation: 70722

Your regular expression syntax is incorrect, you are missing a quantifier after you initial character class in this case it only allows "one" number. Secondly, you are trying to use the concatenation operator ('.') to join both of your named groups together. As well, the last named group is not matching anything.

The following should work for you.

preg_match('/(?P<a>[0-9]+\.[0-9]{2})(?P<supplierPrice>\S+)/', $line, $matches);

Upvotes: 1

Venky
Venky

Reputation: 93

the following works.

\s*(?P<a>\d+\.\d{2})(?P<supplierPrice>[^\s]+)\s*

Demo

Upvotes: 1

gusridd
gusridd

Reputation: 874

In your case it does not match, because you only allow one digit before the dot

[0-9]\.

Should use

[0-9]+\.

if you want any digits before the dot. Then you shall match everything else with

.*

And then the result should be

preg_match("/(?P<a>[0-9]+\.[0-9]{2})(?P<supplierPrice>.*)/", $line, $matches);

Or using \d instead of [0-9]

preg_match("/(?P<a>\d+\.\d{2})(?P<supplierPrice>.*)/", $line, $matches);

Upvotes: 1

Index
Index

Reputation: 736

   preg_match("/(\d{2}\.\d{2})(\d{2}\S{3}\d{2}\S{3})/U", $line, $matches);
   print_r($matches);

Upvotes: 1

anubhava
anubhava

Reputation: 784968

You can use this regex:

^(?P<a>\d+\.\d{2})(?P<supplierPrice>.+)$

Regex Demo

Upvotes: 2

Related Questions