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
https://forums.phpfreaks.com/topic/263398-i-just-need-help/
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
https://forums.phpfreaks.com/topic/263398-i-just-need-help/#findComment-1349883
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
https://forums.phpfreaks.com/topic/263398-i-just-need-help/#findComment-1349884
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
https://forums.phpfreaks.com/topic/263398-i-just-need-help/#findComment-1349912
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
https://forums.phpfreaks.com/topic/263398-i-just-need-help/#findComment-1349913
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
https://forums.phpfreaks.com/topic/263398-i-just-need-help/#findComment-1349918
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • 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.