我的值是这样的:

"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完成了这项工作,但我担心它的性能(它不差,但可以更好)。我的比它快20%。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Perl像:

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

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

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

ECMA脚本:

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

POSIX扩展:

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

或者仅仅是:

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

如果你试图查找只有特定后缀的字符串,比如点语法,你可以尝试这样做:

\"([^\"]*?[^\"]*?)\". 本地化

其中。本地化是后缀。

例子:

打印(“这是我需要归还的东西”。本地化+“所以是这个”。本地化+ "but this is not")

它会捕捉到“这是我需要归还的东西”。本地化和“这也是”。本地化但不是“but this is not”。

特别的是,这些答案都不会产生一个正则表达式,其中返回的匹配是所要求的引号内的文本。MA-Madden尝试了,但只获得了内部匹配,而不是整个匹配。一种实际的方法是:

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

这方面的例子可以在这个演示https://regex101.com/r/Hbj8aP/1中看到

The key here is the the positive lookbehind at the start (the ?<= ) and the positive lookahead at the end (the ?=). The lookbehind is looking behind the current character to check for a quote, if found then start from there and then the lookahead is checking the character ahead for a quote and if found stop on that character. The lookbehind group (the ["']) is wrapped in brackets to create a group for whichever quote was found at the start, this is then used at the end lookahead (?=\1) to make sure it only stops when it finds the corresponding quote.

唯一的另一个复杂之处在于,由于前向查询实际上并不使用结束引号,它将被开始后向查询再次找到,这将导致匹配同一行上结束引号和开始引号之间的文本。在开头引用(["']\b)上加上一个单词边界有助于解决这个问题,尽管理想情况下我想跳过前瞻,但我认为这是不可能的。中间允许转义字符的部分直接取自亚当的回答。