Jump to content

I just need help... :(


AV1611

Recommended Posts

First, hello to those who may remember me from YEARS ago :P

 

Anyways, after all these years, I still suck at regex, so here's a real world problem I need help with:

 

Query returns something like this:

 

C1,C2-6,C7,C14,C15-43

 

or:

 

C1,C2-C6,C7

 

or:

 

CX1,CX2-15

 

or:

 

R1,R2-5,R7

 

etc...

 

Anyways, I need to convert to this format: (I will use the last example)

R1,R2,R3,R4,R5,R7

 

I can use array or whatever, I just don't know how to do the regex to do it...

 

And before I get asked for code, here is what I have so far LOL...

 

<?php

$str="R1,R2-5,R7";

 

?>

Link to comment
Share on other sites

You aren't going to be solving this using regex, at least not all of it. You're going to need to explode the values using the , then us a regex to match the 2-5, then use a for loop to iterate over the values and add them correctly to the array

Link to comment
Share on other sites


$string = "C1,C2-6,C7,C14,C15-43";
$string = explode(",",$string);
$list = array();
foreach ($string as $val) {
  preg_match('~([a-z]+)(\d+)(?:-(\d+))?~i',$val,$parts);
  if ( isset($parts[3]) ) {
    for ($c=$parts[2]; $c<=$parts[3]; $c++) {
      $list[] = $parts[1] . $c;
    }
  } else {
    $list[] = $val;
  }
}
$string = implode(',',$list);

 

edit: modified regex to match 1 or more letter prefix

Link to comment
Share on other sites

You aren't going to be solving this using regex, at least not all of it. You're going to need to explode the values using the , then us a regex to match the 2-5, then use a for loop to iterate over the values and add them correctly to the array

I figured I would have to explode the "," then the -... but how do I get the "alpha" character, seeing it may be 1-3 characters long? i.e. R, C, CX, etc...?

Maybe something that does "grab the beginning of the string until you encounter a number"? How do I do that?

Link to comment
Share on other sites

Oops... one last problem...

 

The data is coming from a VERY old database, and the data syntax is not always the same. The following is possible:

$str="CX1,CX2-6,CX7,CX9-CX11";

 

They did CX2-6, then later CX9-CX11. That seems to be a small issue as well... I am so sorry...

Link to comment
Share on other sites

<?php

$str = "R1,R2-5,R7";
$parts = explode(',', $str);
$out = array();
$regex = '~^([^\d]+)(\d+)-([^\d]*)(\d+)$~';

foreach($parts as $part) {
if(preg_match($regex, $part, $matches)) {
	$range = range($matches[2], $matches[4]);
	foreach($range as $number) {
		$out[] = $matches[1] . $number;
	}
} else {
	$out[] = $part;
}
}

echo '<pre>' . print_r($out, true) . '</pre>';

?>

 

That's how I would do it. Should work for your last example too

Link to comment
Share on other sites

good job Jay, but IMO you unnecessarily complicated it.  No need to group that additional ([^\d]*) and use extra matched index.  Also that would technically match non-alphanumeric chars.  Probably not a concern but may as well be more efficient and explicit since it is assumed that the prefix are alpha only.

 

Also, because I was exceedingly bored, I one-lined it:

 

$string = "CX1,CX2-6,CX7,CX9-CX11";
$string = preg_replace_callback('~([a-z]+)(\d+)(?:-[a-z]*(\d+))?~i',create_function('$m','return (isset($m[3]))?($m[1].implode(\',\'.$m[1],range($m[2],$m[3]))):$m[0];'),$string);
echo $string;

 

output:

 

CX1,CX2,CX3,CX4,CX5,CX6,CX7,CX9,CX10,CX11

Link to comment
Share on other sites

You guys are awesome... I was trying to get the final answer (please don't laugh too loud... it would have worked... but I didn't get part of it right...) anyways, here's my crappy approach. Remember, I don't know regex, but I can improvise LOLOL

 

$string = "CX1,CX2-6,CX7,CX9-CX11";

preg_match('~([a-z]+)(\d+)(?:-(\d+))?~i',$string,$parts);

$prefix = $parts[1];

$string=str_replace(" ","",$string);

$string=str_replace($prefix,"",$string);

$string = explode(",",$string);

$c=count($string);

$i=0;

while($i < $c){

$s=explode("-",$string[$i]);

$ct=count($s);

$ci=0;

while($ci < $ct){

echo $prefix . $s[$ci] . "<br />\r\n";

$ci++;

}

$i++;

}

 

Link to comment
Share on other sites

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.