0

I have a string like this:

some address number 23 neighborhood city

Now, my goal is to separate it in two parts:

  1. some address number 23

  2. neighborhood city

I am guessing this will require a combination of the split or preg_replace commands using something like this /[^0-9]/. No matter how I tried, I did not get the desired result.

Edit: There is 2 absolute correct answers, One using preg_replace and the another one preg_split, Good luck !

2
  • 3
    I would rather match than split ... something trivial such as (.+[0-9]+)(.+) might basically do already. Commented May 18, 2018 at 8:41
  • 1
    Use [0-9]+ to match your integer, then split after the match. Commented May 18, 2018 at 8:41

4 Answers 4

3

You can use preg_split() with flags (PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY)

<?php
$word= "some address number 23 neighborhood city";
$keywords = preg_split("/(.+[0-9]+)(.+)/", $word,-1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
print_r($keywords);

Output:-https://eval.in/1006421

Explanation:-

/(.+[0-9]+)(.+)/

    1st Capturing Group (.+[0-9]+)

        .+ matches any character (except for line terminators)
            + Quantifier — Matches between one and unlimited times, as many times as possible, giving back as needed (greedy)

        Match a single character present in the list below [0-9]+

            + Quantifier — Matches between one and unlimited times, as many times as possible, giving back as needed (greedy)
            0-9 a single character in the range between 0 (index 48) and 9 (index 57) (case sensitive)

    2nd Capturing Group (.+)
        .+ matches any character (except for line terminators)
        + Quantifier — Matches between one and unlimited times, as many times as possible, giving back as needed (greedy)
Sign up to request clarification or add additional context in comments.

5 Comments

Cool, didn't know preg_split could be used like this, thanks ! Now it its hard to select the best answers between you guys.
@DanielIliaguev i ahve added the explanation of regex too
@AlivetoDie he says he wants to separate into 2 parts if there is 2 different numeric values this regex will separate it into 3 parts.
@AlivetoDie is there efficiency difference betweeb preg_match and preg_split for this case ?
@DanielIliaguev no not at all
3
$example = preg_split('/(?<=\d\D)/', 'some address number 23 neighborhood city', 2);

var_dump($example);


array(2) {   
[0]=>   string(20) "some address number 23 "   
[1]=> string(20) "neighborhood city" }

1 Comment

This is definitely the neatest option, but it puts the 23 on the wrong side. I think you might want something like (?<=\d\D) (i.e. positive lookbehind instead of ahead)
2

You can use preg_match and capture groups to match the string properly.

https://3v4l.org/K1IK4

<?php

$string = "some address number 23 neighborhood city";

preg_match("/([^\d]*\d*)(.*)$/", $string, $matches);
var_dump($matches);

array(3) {
    [0]=>
    string(40) "some address number 23 neighborhood city"
    [1]=>
    string(20) "some address number 23"
    [2]=>
    string(18) " neighborhood city"
}

EDIT:

In regex we want to achieve what we want with the lowest steps possible.

This is our regex: https://regex101.com/r/rihbWM/2 and we can see it requires 9 steps which is kinda good.

1st Capturing Group ([^\d]\d)

Match a single character not present in the list below [^\d]* This is performance-wise better than .*\d because .*\d matches the whole string - then has to jump back to the decimal which is worse performance-wise.

  • Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)

\d matches a digit (equal to [0-9])

\d* matches a digit (equal to [0-9])

  • Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)

2nd Capturing Group (.*)

.* matches any character (except for line terminators)

  • Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)

$ asserts position at the end of the string, or before the line terminator right at the end of the string (if any)

4 Comments

Thanks but 2 things, can you explain how you chose to use "/([^\d]*)\d*(.*)$/" ? I would really like to understand that part.. and Second it removes the number from the string, look at the example I need it to be "some address 23" can you tell me how to change that.
@DanielIliaguev Sure, just add the number into the capture group, I edited my answer. I will add in an explanation on why we choose this regex in a second.
@DanielIliaguev Added an explanation for the regex.
Thank you very much ! That sure helps allot to understanding this ! You make me hard time to choose the best answer between all of you... (They all works and detailed explained! )
0

For the tidiest output, split on the space that follows the number. By using \K in the pattern, you release the matched number and only consume the space while exploding.

Code: (Demo)

var_export(
    preg_split("/\d+\K /", $address)
);

If you KNOW that you only want two elements and there might be two separate integers in the string, just set the element limit parameter of preg_split() to 2.

preg_split("/\d+\K /", $address, 2)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.