我想构建一个简单的正则表达式,涵盖引用的字符串,包括其中的任何转义引号。例如,
"This is valid"
"This is \" also \" valid"
显然,像是
"([^"]*)"
不起作用,因为它匹配第一个转义引号。
什么是正确的版本?
我认为其他转义字符的答案是相同的(只需替换相应的字符)。
顺便说一句,我知道“全能”正则表达式
"(.*?)"
但我尽量避免使用它,因为毫不奇怪,它比一个更具体的运行速度慢一些。
答案 0 :(得分:14)
这是我过去使用的一个:
("[^"\\]*(?:\\.[^"\\]*)*")
这将捕获带引号的字符串以及任何转义的引号字符,并排除任何未出现在引号中的内容。
例如,该模式将从此字符串中捕获"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
,并允许字符串中的其他转义码(例如,它将匹配"hello world!\n"
)。
当然,您必须转义模式才能在代码中使用它,如下所示:
"(\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\")"
答案 1 :(得分:3)
试试这个...它更喜欢\"
,如果匹配,它会选择它,否则会选择"
。
"((?:\\"|[^"])*)"
匹配字符串后,您需要获取第一个捕获组的值,并将\"
替换为"
。
编辑:修正了分组逻辑。
答案 2 :(得分:3)
所有其他答案的问题是它们只与最初的明显测试匹配,但没有进行进一步的审查。例如,所有答案都希望第一个引用不会被转义。但最重要的是,转义是一个比单个反斜杠更复杂的过程,因为反斜杠本身可以被转义。想象一下,尝试实际匹配以反斜杠结尾的字符串。怎么可能?
这将是您正在寻找的模式。它并不假设第一个引用是工作引用,它将允许转义反斜杠。
(?<!\\)(?:\\{2})*"(?:(?<!\\)(?:\\{2})*\\"|[^"])+(?<!\\)(?:\\{2})*"
答案 3 :(得分:1)
请在下面的代码中找到包含字符串,数字和十进制的表达式评估的代码。
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...");
}
}
答案 4 :(得分:1)
此
("((?:[^"\\])*(?:\\\")*(?:\\\\)*)*")
将捕获所有字符串(在双引号内),包括\&#34;和\\转义序列。 (请注意,此答案假定字符串中仅转义序列是\&#34;或\\序列 - 不会捕获其他反斜杠字符或转义序列。)
("(?: # 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
<强> Try it out here! 强>
另请注意,maksymiuk's accepted answer包含&#34;边缘情况&#34; (&#34;想象一下,尝试实际匹配以反斜杠结尾的字符串&#34;),这实际上只是一个格式错误的字符串。像
这样的东西"this\"
...不是以反斜杠&#34;结尾的&#34;字符串,而是以转义的引号结尾的未闭合字符串。真正以反斜杠结尾的字符串看起来像
"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
)
有关第二点的更多信息,请参阅this Gist。
答案 5 :(得分:0)
对我有用,比当前答案更简单
(?<!\\+)"(\\"|[^"])*(?<!\\+)"
(?<!\\+)
-在"
之前必须不是\
,并且该表达式是左右。
(\\"|[^"])*
-引号内:可转义的引号\\"
或引号[^"]
以外的任何内容
当前的正则表达式对于以下字符串正常工作:
234
-false
或null
"234"
-true
或["234"]
""
-true
或[""]
"234 + 321 \\"24\\""
-true
或["234 + 321 \\"24\\""]
"234 + 321 \\"24\\"" + 123 + "\\"test(\\"235\\")\\""
-true
或["234 + 321 \\"24\\"", "\\"test(\\"235\\")\\""]
"234 + 321 \\"24\\"" + 123 + "\\"test(\\"235\\")\\"\\"
-true
或["234 + 321 \\"24\\""]