4

I have this:

$only_left_pattern = '/[^-{]\bleft\b/';
$subject = 'body {left: 24px;}\n p {right:30px;}';
$subject = preg_replace($only_left_pattern, 'right', $subject);
echo $subject;

I need to declare a pattern for each string I want to match. If there way I can match right or left and replace according to that? Example (syntax from my head):

$right_left_pattern = '/[^-{](\bleft\b|\bright\b/)';

// if you found left replace with right, if you found right replace with left
// acrording to the order in the pattern
$subject = preg_replace($only_left_pattern, right|left, $subject);

What I'm asking if I can do something like my example with PHP or just with regular expression.

I tried Dave's solution

$pattern = array('/[^-{]\bleft\b/','/[^-{]\bright\b/');
$replace = array('right','left');
$subject = 'body {left: 24px;} p {right: 24px;}';
$subject = preg_replace($pattern, $replace, $subject);
echo $subject;

but it doesn't work, I tested the regex not as array and it's working.

3
  • 3
    preg_replace_callback(), although you can also pass arrays to the first and second arguments of preg_replace() - but I suspect a callback is what you want. Commented Sep 24, 2012 at 11:21
  • 1
    You are asking what now? Commented Sep 24, 2012 at 11:22
  • thanks DaveRandom, tryed this didn't work: $pattern = array('/[^-{]\bleft\b/','/[^-{]\bright\b/'); $replace = array('right','left'); $subject = 'body {left: 24px;} p {right: 24px;}'; $subject = preg_replace($pattern, $replace, $subject); Commented Sep 24, 2012 at 12:56

1 Answer 1

1

The first problem is your regular expression. You have [^-{] that means that you are checking for a string that DOES NOT start with a - or a { but since {left: starts with a { the match is ignoring it. I imagine what you're trying to say is only replace the word left. To replace only part of a string you need to use back references like this:

$pattern = '/([-{]\b)(left)(\b)/';
$replace = '$1right$3';
$subject = 'body {left: 24px;} p {right: 24px;}';
$subject = preg_replace($pattern, $replace, $subject);

// result: body {right: 24px;} p {right: 24px;}
echo $subject;

Notice the parentheses in the $pattern. That is grouping those parts together. Also notice the $n in the $replace. The first parenthesis group ([-{]\b) is $1, the second (left) is $2, and the third (\b) is $3.

Now that solves replacing the left -> right but you can't do the array as suggested because this will happen:

body {left: 24px;} p {right: 24px;}

Step 1: replace left pattern
body {right: 24px;} p {right: 24px;}

Step 2: replace right pattern
body {left: 24px;} p {left: 24px;}

Oops! now you have all left's. That's not very helpful. What you really want is preg_replace_callback. preg_replace_callback will run a user defined function for each match. So what we do is we find all the lefts and rights in one go and then in our function we swap the left/right and return it plus the original string like so:

function replaceLeftRight($matches) {
    // get the opposite left/right
    $leftRight = ($matches[2] == 'left') ? 'right' : 'left';
    return $matches[1] . $leftRight . $matches[3];
}   

$pattern = '/([-{]\b)(left|right)(\b)/';
$subject = 'body {left: 24px;} p {right: 24px;}';    
$subject = preg_replace_callback($pattern, 'replaceLeftRight', $subject);

// result: body {right: 24px;} p {left: 24px;}
echo $subject; 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.