Answers:
我一直在成功使用以下内容:
(["'])(?:(?=(\\?))\2.)*?\1
它也支持嵌套引号。
对于那些想要更深入地解释其工作原理的用户,以下是来自用户的解释:
([""'])
匹配报价;((?=(\\?))\2.)
如果存在反斜杠,请对其进行吞噬,并确定是否匹配字符;*?
多次匹配(非贪婪,以免吃掉最后的报价);\1
匹配用于打开的相同报价。
"foo\"
。前瞻性技巧使?
量词具有所有格(即使正则表达式不支持?+
语法或原子分组)
(["'])(?:\\.|[^\\])*?\1
通常,您要寻找以下正则表达式片段:
"(.*?)"
这使用非贪婪*?运算符可捕获所有内容,但不包括下一个双引号。然后,您使用一种特定于语言的机制来提取匹配的文本。
在Python中,您可以执行以下操作:
>>> import re
>>> string = '"Foo Bar" "Another Value"'
>>> print re.findall(r'"(.*?)"', string)
['Foo Bar', 'Another Value']
"hello \" world"
"(.*?(?<!\\))"
我会去:
"([^"]*)"
在[^“]是除任何字符正则表达式' ” “
我用这个在非贪婪多的运营商的原因是,我要继续找,最多只是为了确保我得到它纠正。
让我们看看处理转义引号的两种有效方法。这些模式的设计既不简洁也不美观,而是有效的。
这些方法使用第一个字符区分来快速查找字符串中的引号,而无需进行替换。(这个想法是在不测试交替的两个分支的情况下,迅速丢弃不是引号的字符。)
引号之间的内容使用展开循环(而不是重复的交替)来描述,以提高效率: [^"\\]*(?:\\.[^"\\]*)*
显然,要处理没有平衡引号的字符串,可以改用所有格修饰符:[^"\\]*+(?:\\.[^"\\]*)*+
或一种变通方法来模仿它们,以防止回溯过多。您也可以选择将加引号的部分用作下一个引号,直到下一个(非转义)引号或字符串的结尾为止。在这种情况下,无需使用所有格修饰符,只需将最后一个引号设为可选。
注意:有时引号不会以反斜杠转义,而是重复引号。在这种情况下,内容子模式如下所示:[^"]*(?:""[^"]*)*
这些模式避免使用捕获组和反向引用(我的意思是类似的东西(["']).....\1
),并使用简单的替代方式,但["']
在开始时要考虑因素。
Perl喜欢:
["'](?:(?<=")[^"\\]*(?s:\\.[^"\\]*)*"|(?<=')[^'\\]*(?s:\\.[^'\\]*)*')
(请注意,这(?s:...)
是在非捕获组内打开点/单行模式的语法糖。如果不支持此语法,则可以轻松为所有模式打开该模式,或将点替换为[\s\S]
)
(此模式的编写方式完全是“手动驱动的”,并且没有考虑最终的引擎内部优化)
ECMA脚本:
(?=["'])(?:"[^"\\]*(?:\\[\s\S][^"\\]*)*"|'[^'\\]*(?:\\[\s\S][^'\\]*)*')
POSIX扩展:
"[^"\\]*(\\(.|\n)[^"\\]*)*"|'[^'\\]*(\\(.|\n)[^'\\]*)*'
或者简单地:
"([^"\\]|\\.|\\\n)*"|'([^'\\]|\\.|\\\n)*'
/pattern/
而不转义任何内容(而不是对象符号new RegExp("(?=[\"'])(?:\"[^\"\\\\]*...");
)
s
here:(?s:
并且(?s)
在模式中的某个位置,则可以使用Perl版本。
接受的答案的RegEx返回值,包括其环绕引号:"Foo Bar"
和"Another Value"
作为匹配项。
这是RegEx,仅返回引号之间的值(如发问者所要求的):
仅双引号(使用捕获组#1的值):
"(.*?[^\\])"
仅单引号(捕获组#1的使用值):
'(.*?[^\\])'
两者(使用捕获组2的值):
(["'])(.*?[^\\])\1
--
所有支持转义和嵌套引号。
src="(.*)"
但显然它选择了最后一个“”之前的所有内容,但是您的REGEX只选择了src =“”内容,但我不知道如何?
奇怪的是,这些答案都不能产生正则表达式,其中返回的匹配项是引号内的文本,这正是要求的内容。MA-Madden尝试但仅将内部比赛作为捕获的小组,而不是整个比赛。一种实际的方法是:
(?<=(["']\b))(?:(?=(\\?))\2.)*?(?=\1)
有关示例,请参见此演示https://regex101.com/r/Hbj8aP/1
此处的关键是开始处的正向后视(?<=
)和结束处的正向前视(?=
)。向后看是在当前字符后方检查报价,如果找到,则从那里开始,然后向前看,检查前面的字符以获取报价,如果找到则停止在该字符上。后面的组(["']
)括在方括号中,以创建一个针对在开头找到的引用的组,然后在结尾处使用该组,以(?=\1)
确保仅在找到相应的引用时才停止。
唯一的其他复杂性是,由于前瞻实际上并没有消耗结束引号,因此将通过后面的开始查找再次找到它,这将导致同一行的结束和开始引号之间的文本匹配。在开头的引号(["']\b
)上放置单词边界可以帮助解决此问题,尽管理想情况下,我希望超越前瞻性,但我认为这是不可能的。我直接从亚当的答案中得到了一点,让中间出现了转义字符。
(["'])(?:(?=(\\?))\2.)*?\1
上面的模式可以完成工作,但我担心它的性能(虽然不错,但可能会更好)。低于它的矿井快20%。
模式"(.*?)"
只是不完整的。我给阅读本书的每个人的建议就是不要使用它!!!
例如,它不能捕获很多字符串(如果需要,我可以提供一个详尽的测试用例),如下所示:
$ string ='你好吗?我
\'
很好,谢谢。
它们的其余部分与上面的那些一样“好”。
如果您确实关心性能和精度,那么请从以下内容开始:
/(['"])((\\\1|.)*?)\1/gm
在我的测试中,它涵盖了我遇到的每个字符串,但是如果您发现不起作用的内容,我会很乐意为您更新。
我喜欢Eugen Mihailescu的解决方案,使引号之间的内容匹配,同时允许转义引号。但是,我发现了转义方面的一些问题,并提出了以下正则表达式来解决它们:
(['"])(?:(?!\1|\\).|\\.)*\1
它可以解决问题,并且仍然非常简单且易于维护。
演示(带有更多测试用例;可以随时使用它并对其进行扩展)。
PS:如果您只想在完全匹配()中的引号之间包含内容$0
,并且不担心使用性能下降,请使用:
(?<=(['"])\b)(?:(?!\1|\\).|\\.)*(?=\1)
不幸的是,没有引号作为锚,我不得不\b
在起始引号之后添加一个边界,该边界不能很好地与空格和非单词边界字符配合使用。
或者,只需添加一个组并提取字符串形式$2
,即可修改初始版本:
(['"])((?:(?!\1|\\).|\\.)*)\1
PPS:如果您只关注效率,请选择Casimir et Hippolyte的解决方案;这是一个很好的。
-
,例如在经度坐标中。
这个版本
控制回溯
/(["'])((?:(?!\1)[^\\]|(?:\\\\)*\\[^\\])*)\1/
更多答案!这是我使用的解决方案
\"([^\"]*?icon[^\"]*?)\"
TLDR;
将单词图标替换为您在引号中看到的内容,瞧!
它的工作方式是它查找关键字,而不关心引号之间的其他内容。EG:
id="fb-icon"
id="icon-close"
id="large-icon-close"
正则表达式先查找引号,"
然后再查找"
直到找到的icon
所有可能的字母组,"
然后再查找不存在的所有可能的字母组"
name="value"
,name={"value"}
因为此答案的正则表达式返回icon
/ value
作为第二组(与接受的答案不同)。找到:=\"([^\"]*?[^\"]*?)\"
更换:={"$1"}
我喜欢Axeman的扩展版本,但遇到了一些麻烦(例如,它不匹配
foo "string \\ string" bar
要么
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
string = "\" foo bar\" \"loloo\""
print re.findall(r'"(.*?)"',string)
只是尝试一下,就像一个魅力!
\
表示跳过字符
" foo bar" "loloo"
。我怀疑您打算像使用regex:一样将其包装在原始字符串中r'"\" foo bar\" \"loloo\""'
。请在适当的时候利用SO出色的格式化功能。不只是化妆品 如果您不使用它们,我们几乎无法说出您要说的话。欢迎使用Stack Overflow!
Microsoft VBA编码器子集的补充答案,只有一个使用该库,Microsoft VBScript Regular Expressions 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
对我来说,这个工作:
|([\'"])(.*?)\1|i
我用过这样的一句话:
preg_match_all('|([\'"])(.*?)\1|i', $cont, $matches);
而且效果很好。
上面所有的答案都很好。。。。除了它们不支持所有的unicode字符!在ECMA脚本(Javascript)
如果您是Node用户,则可能需要支持所有unicode字符的接受答案的修改版本:
/(?<=((?<=[\s,.:;"']|^)["']))(?:(?=(\\?))\2.)*?(?=\1)/gmu
试试这里。
? The preceding token is not quantifiable