1

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

[propertyname]=[value]

thepropertyname和 thevalue都可以用单引号或双引号封装。

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

"height"='max'

或者:

'height'='max'

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

我需要做的是删除引号。但只在propertynameand周围value!因为以下也很可能是一个有效的字符串:

"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电话,但考虑到正则表达式应该能够在一个电话中处理这个问题,这是一个令人讨厌的工作......

知道问题是什么吗?

4

2 回答 2

4

您的正则表达式应该正确匹配,但是您有一个问题:在您的“组合正则表达式”中,$1指的是整个匹配项(因为第一组括号包含整个匹配项),因此您将匹配项替换为自身,包括引号。

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

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

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

但是你有一个不同的问题:你要么需要用$1or替换匹配$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);
于 2012-12-11T14:40:27.893 回答
1

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

'#"(.*?)"#'
// or
'#(?:"(.*?)"|\'(.*?)\')#'
于 2012-12-11T15:02:08.480 回答