我的值是这样的:

"Foo Bar" "Another Value" something else

什么正则表达式将返回括在引号中的值(例如Foo Bar和Another Value)?


当前回答

模式(["'])(?:(?=(\\?))\2.)*?上面的\1完成了这项工作,但我担心它的性能(它不差,但可以更好)。我的比它快20%。

模式“(.*?)”是不完整的。我对阅读这篇文章的人的建议是不要使用它!!

例如,它不能捕获很多字符串(如果需要,我可以提供一个详尽的测试用例),如下所示:

$string = '你好吗?我很好,谢谢你;

其余的都和上面那个一样“好”。

如果你真的关心性能和精度,那么就从下面的开始:

/(['"])((\\\ 1 |。)* ?)\ 1 /通用

在我的测试中,它涵盖了我遇到的每一个字符串,但如果你发现一些不工作的东西,我很乐意为你更新它。

在在线正则表达式测试器中检查我的模式。

其他回答

更多的答案!这是我使用的解决方案

\"([^\"]*? 图标 [^\"]*?)\"

TLDR; 替换词图标与你所寻找的说语录,瞧!


它的工作方式是寻找关键字,而不关心引号之间的其他内容。 例如: id = " fb-icon " id = " icon-close " id = " large-icon-close " 正则表达式查找引号" 然后它寻找任何可能的字母组,而不是“ 直到找到图标 任何可能的字母组都不是" 然后它会寻找一个结束。”

我一直在使用以下方法并取得了巨大的成功:

(["'])(?:(?=(\\?))\2.)*?\1

它还支持嵌套引号。

对于那些想要更深入地解释这是如何工作的人,这里是用户ephemerent的解释:

([""'])匹配引号;((?=(\\?))\2.)如果存在反斜杠,吞噬它,无论是否发生,匹配一个字符;* ?匹配多次(非贪婪,如不吃结尾引号);\1匹配相同的报价,是用于开幕。

我喜欢《Axeman》更广阔的版本,但也遇到了一些问题(游戏邦注:例如它并不匹配

foo "string \\ string" bar

or

foo "string1"   bar   "string2"

所以我试着修正它:

# opening quote
(["'])
   (
     # repeat (non-greedy, so we don't span multiple strings)
     (?:
       # anything, except not the opening quote, and not 
       # a backslash, which are handled separately.
       (?!\1)[^\\]
       |
       # consume any double backslash (unnecessary?)
       (?:\\\\)*       
       |
       # Allow backslash to escape characters
       \\.
     )*?
   )
# same character as opening quote
\1

我认为:

"([^"]*)"

[^"]是除'"'以外的任何字符的正则表达式 我用这个代替非贪婪多算子的原因是我需要不断地查找以确保我得到的是正确的。

我喜欢Eugen Mihailescu的解决方案,在允许转义引号的同时匹配引号之间的内容。然而,我发现了一些转义的问题,并提出了以下正则表达式来解决它们:

(['"])(?:(?!\1|\\).|\\.)*\1

它做到了这一点,而且仍然非常简单,易于维护。

演示(包含更多的测试用例;请随意使用并扩展它)。


PS:如果你只是想在引号之间的内容完全匹配($0),并不怕性能惩罚使用:

(?<=(['"])\b)(?:(?!\1|\\).|\\.)*(?=\1)

不幸的是,没有引号作为锚,我不得不添加一个边界\b,它不能很好地处理开始引号后的空格和非单词边界字符。

或者,修改初始版本,只需添加一个组,并从$2中提取字符串:

(['"])((?:(?!\1|\\).|\\.)*)\1

PPS:如果你只关注效率,那就选择Casimir和Hippolyte的解决方案;这是一个很好的例子。