Daniel Iliaguev
Daniel Iliaguev

Reputation: 49

PHP split string before and after the integer inside

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 !

Upvotes: 0

Views: 1007

Answers (4)

mickmackusa
mickmackusa

Reputation: 48091

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)

Upvotes: 0

xate
xate

Reputation: 6379

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)

Upvotes: 2

Death-is-the-real-truth
Death-is-the-real-truth

Reputation: 72269

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)

Upvotes: 3

Anar Bayramov
Anar Bayramov

Reputation: 11594

$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" }

Upvotes: 3

Related Questions