用于匹配转义字符的正则表达式(引号)

我想构建一个简单的正则表达式,涵盖引用的字符串,包括其中的任何转义引号。 例如,

"This is valid" "This is \" also \" valid" 

显然,像

 "([^"]*)" 

不起作用,因为它匹配第一个转义引用。

什么是正确的版本?

我想其他转义字符的答案是相同的(只需替换相应的字符)。

顺便说一句,我知道“全能”正则表达式

 "(.*?)" 

但我尽量避免使用它,因为毫不奇怪,它比一个更具体的运行速度慢一些。

所有其他答案的问题是它们只与最初的明显测试匹配,但没有进行进一步的审查。 例如,所有答案都希望第一个引用不会被转义。 但最重要的是,转义是一个比单个反斜杠更复杂的过程,因为反斜杠本身可以被转义。 想象一下,尝试实际匹配以反斜杠结尾的字符串。 怎么可能呢?

这将是您正在寻找的模式。 它不假设第一个引用是工作引用,它将允许转义反斜杠。

 (? 

这是我过去使用过的一个:

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

这将捕获带引号的字符串以及任何转义的引号字符,并排除任何未出现在引号中的内容。

例如,模式将从此字符串中捕获"This is valid""This is \" also \" valid"

 "This is valid" this won't be captured "This is \" also \" valid" 

这种模式与字符串"I don't \"have\" a closing quote 匹配"I don't \"have\" a closing quote ,并允许字符串中的其他转义码(例如,它将匹配"hello world!\n" )。

当然,您必须转义模式才能在代码中使用它,如下所示:

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

尝试这个…它更喜欢\" ,如果匹配,它将选择它,否则它会选择"

 "((?:\\"|[^"])*)" 

匹配字符串后,您需要获取第一个捕获组的值并替换\" with "

编辑:修复了分组逻辑。

请在下面的代码中找到包含StringNumberDecimal的表达式求值的代码。

 public static void commaSeparatedStrings() { String value = "'It\\'s my world', 'Hello World', 'What\\'s up', 'It\\'s just what I expected.'"; if (value.matches("'([^\'\\\\]*(?:\\\\.[^\'\\\\])*)[\\w\\s,\\.]+'(((,)|(,\\s))'([^\'\\\\]*(?:\\\\.[^\'\\\\])*)[\\w\\s,\\.]+')*")) { System.out.println("Valid..."); } else { System.out.println("Invalid..."); } } /** * */ public static void commaSeparatedDecimals() { String value = "-111.00, 22111.00, -1.00"; // "\\d+([,]|[,\\s]\\d+)*" if (value.matches( "^([-]?)\\d+\\.\\d{1,10}?(((,)|(,\\s))([-]?)\\d+\\.\\d{1,10}?)*")) { System.out.println("Valid..."); } else { System.out.println("Invalid..."); } } /** * */ public static void commaSeparatedNumbers() { String value = "-11, 22, -31"; if (value.matches("^([-]?)\\d+(((,)|(,\\s))([-]?)\\d+)*")) { System.out.println("Valid..."); } else { System.out.println("Invalid..."); } } 

这个

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

将捕获所有字符串(在双引号内),包括\“和\\转义序列。(请注意,此答案假定您的字符串中唯一的转义序列是\”或\\序列 – 没有其他反斜杠字符或转义序列将被捕获。)

 ("(?: # begin with a quote and capture... (?:[^"\\])* # any non-\, non-" characters (?:\\\")* # any combined \" sequences (?:\\\\)* # and any combined \\ sequences )* # any number of times ") # then, close the string with a quote 

试试吧!

另外,请注意maksymiuk接受的答案包含一个“边缘案例”(“想象实际上试图匹配以反斜杠结尾的字符串”),这实际上只是一个格式错误的字符串。 就像是

 "this\" 

…不是“以反斜杠结尾的字符串”,而是以转义的引号结尾的未闭合字符串。 真正以反斜杠结尾的字符串看起来像

 "this\\" 

……以上解决方案处理这种情况。


如果你想扩大一点,这……

 (\\(?:b|t|n|f|r|\"|\\)|\\(?:(?:[0-2][0-9]{1,2}|3[0-6][0-9]|37[0-7]|[0-9]{1,2}))|\\(?:u(?:[0-9a-fA-F]{4}))) 

…捕获所有常见的转义序列(包括转义引号):

 (\\ # get the preceding slash (for each section) (?:b|t|n|f|r|\"|\\) # capture common sequences like \n and \t |\\ # OR (get the preceding slash and)... # capture variable-width octal escape sequences like \02, \13, or \377 (?:(?:[0-2][0-9]{1,2}|3[0-6][0-9]|37[0-7]|[0-9]{1,2})) |\\ # OR (get the preceding slash and)... (?:u(?:[0-9a-fA-F]{4})) # capture fixed-width Unicode sequences like \u0242 or \uFFAD ) 

有关第二点的更多信息,请参阅此要点 。