4

我有这个:

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

我需要为要匹配的每个字符串声明一个模式。如果有办法我可以左右匹配并据此替换?示例(我脑海中的语法):

$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);

我在问我是否可以使用 PHP 或仅使用正则表达式来执行类似我的示例的操作。

我尝试了戴夫的解决方案

$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;

但它不起作用,我测试了regexnot as 数组并且它正在工作。

4

1 回答 1

1

第一个问题是你的正则表达式。你有[^-{]这意味着你正在检查一个不以 a-或 a开头{但因为{left:以 a开头的字符串,{所以匹配忽略它。我想你想说的只是替换这个词left。要仅替换字符串的一部分,您需要使用这样的反向引用:

$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;

注意 . 中的括号$pattern。那就是将这些部分组合在一起。还要注意$n. $replace第一个括号组([-{]\b)$1,第二个(left)$2,第三个(\b)$3

现在解决了替换左->右的问题,但是您不能按照建议执行数组,因为这会发生:

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;}

哎呀!现在你已经全部离开了。这不是很有帮助。你真正想要的是preg_replace_callbackpreg_replace_callback将为每个匹配运行一个用户定义的函数。所以我们要做的是一次性找到所有的左和右,然后在我们的函数中我们交换左/右并返回它加上原始字符串,如下所示:

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; 
于 2013-06-06T17:30:51.147 回答