preg_replace和'|' (或)不在我的正则表达式中工作

时间:2012-12-11 14:34:14

标签: php regex preg-replace

我有一个像这样构建的字符串:

[propertyname]=[value]

propertynamevalue都可以用单引号或双引号封装。

所以我可以收到一个看起来像这样的字符串:

"height"='max'

或:

'height'='max'

只要propertynamevalue都用相同类型的引号封装。

我需要做的是删除引号。但只能在propertynamevalue附近!因为以下内容很可能也是一个有效的字符串:

"blaat"="Some 'random' blaat"

最终结果应为:

blaat=Some 'random' blaat

我有以下正则表达式有效。但它只适用于我要么检查双引号还是单引号。当我尝试将它们与|运算符组合时,它就不再起作用了。

<?php
$string = '"height"=\'something "else" in here\'';

//echo preg_replace ( '#"(.*?)"#', '$1', $string );
//echo preg_replace ( '#\'(.*?)\'#', '$1', $string );
echo preg_replace ( '#("(.*?)"|\'(.*?)\')#', '$1', $string );
?>

所以我可以简单地做两个preg_replace调用,但这是一个令人讨厌的工作,考虑正则表达式应该能够在一次调用中处理这个......

知道问题是什么吗?

2 个答案:

答案 0 :(得分:4)

你的正则表达式应该正确匹配,但你有一个问题:在你的“组合正则表达式”中,$1指的是整个匹配(因为第一组括号包围整个匹配),所以你是用自己替换匹配,包括引号。

("(.*?)"|\'(.*?)\')
^ ^        ^
|-+--- $1  |---- $3
  |--- $2

现在,您可以简单地删除外括号:

"(.*?)"|\'(.*?)\'
 ^        ^
 |--- $1  |---- $2

但是你有一个不同的问题:你需要用$1$2替换匹配,具体取决于正则表达式的哪一半匹配。既然你事先无法知道,那就不容易了。您可以可能尝试替换为$1$2,但我不知道PHP是否允许对未参与匹配的组进行反向引用。

更好地发挥其安全性并使用可以同时处理两种情况的正则表达式,包括引用字符串中的转义引号:

$result = preg_replace(
    '/(        # Match and capture (group 1):
     ["\']     # an opening quote character
    )          # (End of group 1).
    (          # Now match and capture (group 2):
     (?:       #  Either...
      \\\\.    #   an escaped character
     |         #  or...
      (?!\1)   #   (as long as it is not the closing quote)
      .        #   any other character.
     )*        #  Repeat as needed.
    )          # (End of group 2)
    \1         # Now match the closing quote./x', 
    '\2', $subject);

答案 1 :(得分:1)

使用类["']来捕获两个引号,或者使用非捕获组(?:)以避免由于括号括起而产生额外的捕获组:

'#"(.*?)"#'
// or
'#(?:"(.*?)"|\'(.*?)\')#'