我的值是这样的:

"Foo Bar" "Another Value" something else

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


当前回答

对于Microsoft VBA编码器子集的补充回答,只有一个人使用Microsoft VBScript正则表达式5.5库,这给出了以下代码

Sub TestRegularExpression()

    Dim oRE As VBScript_RegExp_55.RegExp    '* Tools->References: Microsoft VBScript Regular Expressions 5.5
    Set oRE = New VBScript_RegExp_55.RegExp

    oRE.Pattern = """([^""]*)"""


    oRE.Global = True

    Dim sTest As String
    sTest = """Foo Bar"" ""Another Value"" something else"

    Debug.Assert oRE.test(sTest)

    Dim oMatchCol As VBScript_RegExp_55.MatchCollection
    Set oMatchCol = oRE.Execute(sTest)
    Debug.Assert oMatchCol.Count = 2

    Dim oMatch As Match
    For Each oMatch In oMatchCol
        Debug.Print oMatch.SubMatches(0)

    Next oMatch

End Sub

其他回答

接受的答案的RegEx返回值,包括它们的寻源引号:“Foo Bar”和“Another Value”作为匹配。

下面是RegEx,它只返回引号之间的值(正如提问者所要求的那样):

仅使用双引号(使用捕获组#1的值):

"(.*?[^\\])"

仅使用单引号(使用捕获组#1的值):

'(.*?[^\\])'

Both(使用捕获组#2的值):

([']) "(. *? 1 \ [^ \ \])

-

全部支持转义和嵌套引号。

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

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

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

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


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

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

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

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

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

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

让我们看看处理转义引号的两种有效方法。这些模式不是为了简洁或美观而设计的,而是为了高效。

这些方法使用第一个字符区分快速查找字符串中的引号,而不需要进行替换。(这个想法是快速丢弃不是引号的字符,以测试交替的两个分支。)

引号之间的内容用一个展开的循环(而不是重复的交替)来描述,这样也更有效率:[^"\\]*(?:\\.[^"\\]*)*

显然,要处理没有平衡引号的字符串,可以使用所有格量词:[^"\\]*+(?:\\.[^"\\]*)*+或模仿它们的替代方法,以防止太多回溯。你也可以选择一个带引号的部分可以是一个开始引号,直到下一个(非转义)引号或字符串的结尾。在这种情况下,没有必要使用所有格量词,你只需要使最后一个引用是可选的。

注意:有时引号不是用反斜杠转义,而是通过重复引号转义。在这种情况下,内容子模式看起来像这样:[^"]*(?:""[^"]*)*

这些模式避免使用捕获组和反向引用(我的意思是(["']).....\1),并使用简单的替换,但在factor开头使用["']。

Perl像:

["'](?:(?<=")[^"\\]*(?s:\\.[^"\\]*)*"|(?<=')[^'\\]*(?s:\\.[^'\\]*)*')

(注意,(?s:…)是一个语法糖,用于在非捕获组中打开dotall/单线模式。如果不支持此语法,您可以轻松地为所有模式打开此模式或将点替换为[\s\ s])

(这种模式的编写方式完全是“手工驱动的”,没有考虑到最终的引擎内部优化)

ECMA脚本:

(?=["'])(?:"[^"\\]*(?:\\[\s\S][^"\\]*)*"|'[^'\\]*(?:\\[\s\S][^'\\]*)*')

POSIX扩展:

"[^"\\]*(\\(.|\n)[^"\\]*)*"|'[^'\\]*(\\(.|\n)[^'\\]*)*'

或者仅仅是:

"([^"\\]|\\.|\\\n)*"|'([^'\\]|\\.|\\\n)*'

一般来说,下面的正则表达式片段就是你要找的:

"(.*?)"

这使用了非贪婪的*?运算符来捕获下一个双引号之前的所有内容。然后,使用特定于语言的机制提取匹配的文本。

在Python中,你可以这样做:

>>> import re
>>> string = '"Foo Bar" "Another Value"'
>>> print re.findall(r'"(.*?)"', string)
['Foo Bar', 'Another Value']

很晚才回答,却喜欢回答

(\"[\w\s]+\")

http://regex101.com/r/cB0kB8/1