Jump to content

Splitting a string based on the last instance of a character


Recommended Posts

Hi!

 

I am trying to figure out how I can split a string based on the last of several instances of a character that exists within a string and return just the two parts. For example: netstat displays IPv6 addresses with the port number attached via a colon. But the colon is also used for the hextets in the address.

 

2001:db8:a0b:12f0::1:25

 

While this IP/Port have many colons, I am trying to split by the very last one to get the results:

 

2001:db8:a0b:12f0::1

25

 

This doesn't seem like it should be difficult, but yet I am struggling to get it to work with various combinations of preg_split or strrchr.

 

Can annyone offer any advice? I have a feeling the answer is going to make me go "duh, of course!" 

Not being able to think of any nicer solution, I'd go with substr() and strrpos().

$ipport = "2001:db8:a0b:12f0::1:25";
$p = strrpos($ipport, ":");
$ip = substr($ipport, 0, $p);
$port = substr($ipport, $p + 1);
  • Like 1

To expand onto Barand's to get first part back minus port.

$ipport = "2001:db8:a0b:12f0::1:25";
$end = strrchr($ipport, ':');
$first = substr($ipport, 0, -strlen($end));
echo $first; //2001:db8:a0b:12f0::1
echo $end; //--> :25

Thank you so much. I hadn't thought about doing it in two steps (one for first part, one for second part). Makes sense!

EDIT: I had the browser window open over night and did not refresh it to see there were additional responses since requinix. So thank you everyone who responded.

Edited by sn00pers

 

$split_chr = ':';
$parts = explode($split_chr,$source);
$sz = count($parts) -1;
$part1 = '';
for ($i=0; $i<$sz-1; $i++)
$part1 .= $parts[$i];
$part2 = $parts[$sz];

 

If you're going to use explode, then might as well use pop() to remove the last element and implode() the remaining elements back together

$split_chr = ':';
$parts = explode($split_chr, $source);
$last = pop($parts);
$first = implode(':', $parts);
Edited by Psycho

Hmmm, I must not understand the question. OP wanted two parts - one with the first n pieces and one with just the last piece. That seems to be what his/her example shows. Using the implode to build the first part is a good idea, but you have lost the last part.

Sorry if I was confusing. I was looking to end up with two strings. The IP, and the Port. I just had to add a little tweak to remove the colon from the port number, but all is working.

Edited by sn00pers

Hmmm, I must not understand the question. OP wanted two parts - one with the first n pieces and one with just the last piece. That seems to be what his/her example shows. Using the implode to build the first part is a good idea, but you have lost the last part.

 

I only lost the last part because I used pop() instead of the correct nomenclature of array_pop(). Other than that, the code retrieves both parts

$source = "2001:db8:a0b:12f0::1:25";
 
$split_chr = ':';
$parts = explode($split_chr, $source);
$last = array_pop($parts);
$first = implode(':', $parts);
 
echo "First: {$first}<br>\n";
echo "Last: {$last}<br>\n";

 

 

First: 2001:db8:a0b:12f0::1

Last: 25

Edited by Psycho

Here's a quick one:

preg_match('/^(.*)\d+)$/', "2001:db8:a0b:12f0::1:25", $match) && list(, $ip, $port) = $match;
(I was deliberately avoiding doing this with my first answer)

 

 

I think I used that regex before I posted this thread, but was trying a preg_split with it so that might be why I wasn't able to get it to work. I often use preg_match and then an additional line to get a string from the output array. What you did here looked really interesting. How does the and part work here? I like that it's one line because it makes it clear that it's all part of the same operation.

What you did here looked really interesting. How does the and part work here? I like that it's one line because it makes it clear that it's all part of the same operation.

Don't use it as a matter of practice. It's just a clever way of doing two commands at once; if the regex failed then $ip and $port would be undefined.

 

You know $x && $y? $y doesn't get evaluated unless $x is true, and if $x is false then it does not. And since preg_match() returns 1 (which is "true") if it matches, the assignment only gets evaluated if the regex matched.

I haven't used really used $x && $y types of evaluations before so now I need to start thinking about where I can incorporate that.

Please don't. You'll encourage me to never post stuff like that again.

 

I only ever use it with really, really simple stuff. Like

$variable && function_call($variable);
or

isset($array["value"]) && $obj->property = $array["value"];
You can see what it's doing at a quick glance. No thinking involved. That thing with the regex and the list() is too complicated: you have to think "okay, what is preg_match() returning and what are the values in $match and why is list() skipping the first array value" and it's just a hassle.
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.