简体   繁体   中英

Doubt on Regular expressions in PHP

Friends,

I have a silly doubt:

Assume that I have a line like this

Heading: Value1; SomeText1 (a, b, c), Value 2; SomeText2 (d, e, f)

I wanted to remove all semicolon and remove everything in brackets (including brackets). I managed to do this using this code

if (strstr($line,'Heading')){
                $new_heading = str_replace(";", "", $line); // Replaces semi-colon
                $new_heading = preg_replace("/\([^\)]+\)/","",$new_heading); //Removes Text With in Brackets
                $line = $new_heading;
                echo $line; //Outputs "Heading: Value1 SomeText1 , Value 2 SomeText2"
                } 

Now Assume I have a line like this

Heading: Text1 (a, b) Text2. (d, f) Text3 (g, h)

What I want to achieve is... Remove everything with in brackets (inclusive brackets) and replace it with comma. However the last ocurance of the bracket should not be replace with a comma.

I mean the output should be

Heading: Text1 , Text2. , Text3

How to achive this?

If you just want to remove the trailing comma, you could just use substr...

$newstr = substr($str, 0, strlen($str)-1);  

Something like that...

EDIT:> Ok attempting to answer this again ... Will this work ?

$new_heading = preg_replace("/\([^\)]+\)/",",",$new_heading);
$newstr = substr($new_heading, 0, strlen($str)-1);  

EDIT:> In response to your comment below. Thanks :) I didn't really use a book, just RegxLib

(Updated) Try this,

$text = "Heading: Text1 (a, b) Text2. (d, f) Text3 (g, h)";

preg_match_all("/\([^\)]+\)/",$text, $brackets);

$bracket_c = count($brackets);

for($bracket_i = 0; $bracket_i < $bracket_c; $bracket_i += 1){
    if($bracket_i == $bracket_c - 1){
        $text = str_replace($brackets[$bracket_i], "", $text);
    }else{
        $text = str_replace($brackets[$bracket_i], ",", $text);
    }
}
echo $text . "\n";

If you look at the definition of preg_replace() there is a parameter called $limit . So here are the steps to solve your problem:

  1. use preg_match_all to count the brackets
  2. use that number - 1 in the preg_replace and replace the brackets with commas
  3. use preg_replace again to replace the last bracket with an empty string

Code:

preg_match_all("/\([^\)]+\)/",$new_heading,$matches);
$new_heading = preg_replace("/\([^\)]+\)/",",",$new_heading, count($matches) - 1);
$new_heading = preg_replace("/\([^\)]+\)/","",$new_heading);

Alternative:

  1. use preg_replace as before, but do not store the result. Only use the value of $count which is the fifth parameter.
  2. use that number - 1 in the preg_replace and replace the brackets with commas
  3. use preg_replace again to replace the last bracket with an empty string

Code:

preg_replace("/\([^\)]+\)/","",$new_heading, null, $count);
$new_heading = preg_replace("/\([^\)]+\)/",",",$new_heading, $count - 1);
$new_heading = preg_replace("/\([^\)]+\)/","",$new_heading);

Can you use two expressions?

$text = "Heading: Text1 (a, b) Text2. (d, f) Text3 (g, h)";

$new = preg_replace("/\([^)]*\)(?=.*?\([^)]*\))/",",",$text);
$new = preg_replace("/\([^)]*\)/","",$new);

echo $new . "\n";

The first one replaces all instances but the last with commas. The last instance (g, h) remains. Then the second expression replaces all remaining instances (which is just one) with an empty string.

<?php
$line = 'Heading: Text1 (a, b) Text2. (d, f) Text3 (g, h)';
$line = substr(preg_replace('/\([^\)]+\)/', ',', $line), 0, -1);
?>

Or with two regexes you can do:

<?php
$line = 'Heading: Text1 (a, b) Text2. (d, f) Text3 (g, h)';
$line = preg_replace('/ \([^\)]+\)$/', '', $line);
$line = preg_replace('/\([^\)]+\)/', ',', $line);
?>

But that's overkill. Use one regex for simplicity.

this might look inefficient but will solve your problem. the strategy is

  • use preg_match to find out the number of occurrences of pattern, in this case its brackets and say its n
  • use preg_replace to replace the occurrences of n-1 brackets by comma setting the limit parameter to n-1
  • use preg_replace to replace the set of brackets by empty string

Use code like this:

$str = 'Text1 (a, b) Text2. (d, f) Text3 (g, h)';
$arr = preg_split('~\([^)]*\)~', $str, -1 , PREG_SPLIT_NO_EMPTY);
var_dump(implode(',', $arr));

OUTPUT

string(23) "Text1 , Text2. , Text3 "

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM