我有一个正则表达式来查找引号之间的值:
([\"'])(?:\\\1|.)*?\1
这很好用,但是,如果引号之间有双引号,那么它也会失败并拆分它们。例如。
"value1","value2","value with "" is here","value4"
我需要像这样的输出
value1
value2
value with "" is here
value4
这意味着,如果双引号出现在某处,它应该在输出中返回它。有人能帮忙吗?
我的第一个想法是通过将双引号添加到您的交替中来允许双引号:
([\"'])(?:\\\1|\1\1|.)*?\1
但是,由于您已经使量词变得惰性,因此这仍然无法正常工作。最好明确指出引号之间不允许使用未转义的引号:
([\"'])(?:\\\1|\1\1|(?!\1).)*\1
在regex101上查看。
解释:
([\"']) # Match a quote, remember which kind in group 1.
(?: # Start non-capturing group:
\\\1 # Either match a backslash-escaped quote
| # or
\1\1 # a doubled quote
| # or
(?!\1) # (as long as it's not a quote)
. # any character.
)* # Repeat as necessary
\1 # Match a corresponding quote
您的输入看起来像 CSV 记录,其中通过添加另一个引号来转义文字引号。你是说你也可以用反斜杠转义引用吗?我从未见过;通常是其中之一。而且我从未见过 CSV 变体可以让您在同一记录中的单引号(撇号)或双引号之间交替。您可能使这比需要的更复杂。
假设只有双引号被识别为字段分隔符,并且它们只能通过添加另一个引号来转义,匹配一个字段非常简单:
(?:"[^"]*")+
反斜杠转义版本稍微复杂一些:
"[^"\\]*(?:\\.[^"\\]*)*"
如果也允许使用单引号分隔符,最简单的方法是添加另一种选择:
(?:"[^"]*")+|(?:'[^']*')+
"[^"\\]*(?:\\.[^"\\]*)*"|'[^'\\]*(?:\\.[^'\\]*)*'
如果您真的需要支持两种引用和两种转义,请参阅 Tim 的回答。但我非常怀疑。