2

Let's say I want to split this string in two variables:

$string = "levis 501";

I will use

preg_match('/\d+/', $string, $num);
preg_match('/\D+/', $string, $text);

but then let's say I want to split this one in two

$string = "levis 5° 501";

as $text = "levis 5°"; and $num = "501";

So my guess is I should add a rule to the preg_match('/\d+/', $string, $num); that looks for numbers only at the END of the string and I want it to be between 2 and 3 digits. But also the $text match now has one number inside...

How would you do it?

syck
  • 2,857
  • 1
  • 10
  • 20
Chriz74
  • 1,250
  • 2
  • 19
  • 35

1 Answers1

2

To slit a string in two parts, use any of the following:

preg_match('~^(.*?)\s*(\d+)\D*$~s', $s, $matches);

This regex matches:

  • ^ - the start of the string
  • (.*?) - Group 1 capturing any one or more characters, as few as possible (as *? is a "lazy" quantifier) up to...
  • \s* - zero or more whitespace symbols
  • (\d+) - Group 2 capturing 1 or more digits
  • \D* - zero or more characters other than digit (it is the opposite shorthand character class to \d)
  • $ - end of string.

The ~s modifier is a DOTALL one forcing the . to match any character, even a newline, that it does not match without this modifier.

Or

preg_split('~\s*(?=\s*\d+\D*$)~', $s);

This \s*(?=\s*\d+\D*$) pattern:

  • \s* - zero or more whitespaces, but only if followed by...
  • (?=\s*\d+\D*$) - zero or more whitespaces followed with 1+ digits followed with 0+ characters other than digits followed with end of string.

The (?=...) construct is a positive lookahead that does not consume characters and just checks if the pattern inside matches and if yes, returns "true", and if not, no match occurs.

See IDEONE demo:

$s = "levis 5° 501";
preg_match('~^(.*?)\s*(\d+)\D*$~s', $s, $matches);
print_r($matches[1] . ": ". $matches[2]. PHP_EOL);
print_r(preg_split('~\s*(?=\s*\d+\D*$)~', $s, 2));
Wiktor Stribiżew
  • 484,719
  • 26
  • 302
  • 397
  • this one is working for me `"/^(.*?)\\s*(\\d+)$/"` . Could you or anyone point me to a tutorial or something on patterns? – Chriz74 Mar 08 '16 at 19:13
  • I do not know your level of regex knowledge :) so that I can only suggest doing all lessons at [regexone.com](http://regexone.com/), reading through [regular-expressions.info](http://www.regular-expressions.info), [regex SO tag description](http://stackoverflow.com/tags/regex/info) (with many other links to great online resources), and the community SO post called [What does the regex mean](http://stackoverflow.com/questions/22937618/reference-what-does-this-regex-mean). – Wiktor Stribiżew Mar 08 '16 at 19:21
  • I have added explanations. – Wiktor Stribiżew Mar 08 '16 at 19:27
  • 1
    Hello, thanks I checked it, I used this "/^(.*?)\\s*(\\d+)$/" as it seems it's working correctly. Thanks for the clarifications and links, I checked. – Chriz74 Mar 09 '16 at 16:50
  • Very glad. Thank you for an interesting question. Keep them coming! :-) – Wiktor Stribiżew Mar 09 '16 at 17:01