【发布时间】:2015-12-22 23:17:55
【问题描述】:
我有一种语言将字符串定义为由单引号或双引号分隔,其中分隔符通过加倍在字符串中进行转义。例如,以下所有字符串都是合法字符串:
'This isn''t easy to parse.'
'Then John said, "Hello Tim!"'
"This isn't easy to parse."
"Then John said, ""Hello Tim!"""
我有一个字符串集合(上面定义),由不包含引号的东西分隔。我试图使用正则表达式做的是解析列表中的每个字符串。例如,这是一个输入:
"Some String #1" OR 'Some String #2' AND "Some 'String' #3" XOR
'一些“字符串”#4'你好“一些”“字符串”“#5”FOO'一些''字符串''#6'
判断一个字符串是否是这种形式的正则表达式很简单:
^(?:"(?:[^"]|"")*"|'(?:[^']|'')*')(?:\s+[^"'\s]+\s+(?:"(?:[^"]|"")*"|'(?:[^']|'')*')*
在运行上面的表达式来测试它是否是这种形式之后,我需要另一个正则表达式来从输入中获取每个分隔字符串。我打算这样做:
Pattern pattern = Pattern.compile("What REGEX goes here?");
Matcher matcher = pattern.matcher(inputString);
int startIndex = 0;
while (matcher.find(startIndex))
{
String quote = matcher.group(1);
String quotedString = matcher.group(2);
...
startIndex = matcher.end();
}
我想要一个正则表达式,它可以捕获第 1 组中的引号字符和第 2 组中引号内的文本(我使用的是 Java 正则表达式)。因此,对于上述输入,我正在寻找一个在每次循环迭代中产生以下输出的正则表达式:
Loop 1: matcher.group(1) = "
matcher.group(2) = Some String #1
Loop 2: matcher.group(1) = '
matcher.group(2) = Some String #2
Loop 3: matcher.group(1) = "
matcher.group(2) = Some 'String' #3
Loop 4: matcher.group(1) = '
matcher.group(2) = Some "String" #4
Loop 5: matcher.group(1) = "
matcher.group(2) = Some ""String"" #5
Loop 6: matcher.group(1) = '
matcher.group(2) = Some ''String'' #6
到目前为止我尝试过的模式(未转义,然后是 Java 代码的转义):
(["'])((?:[^\1]|\1\1)*)\1
"([\"'])((?:[^\\1]|\\1\\1)*)\\1"
(?<quot>")(?<val>(?:[^"]|"")*)"|(?<quot>')(?<val>(?:[^']|'')*)'
"(?<quot>\")(?<val>(?:[^\"]|\"\")*)\"|(?<quot>')(?<val>(?:[^']|'')*)'"
在尝试编译模式时,这两个都失败了。
这样的正则表达式可能吗?
【问题讨论】:
-
See the Javadoc。他们没有提到支持反斜杠引用:(
-
在您链接的页面的大约四分之一处,有一个标题为“反向引用”的部分,其中包含文本“\n 无论第 n 个捕获组匹配”。
-
您想在第二组中捕获的“引号之间的文本”是什么?是
this isn''t easy to parse(转义)还是this isn't easy to parse未转义? -
绝对有必要使用正则表达式来解决这个问题,还是可以编写一些代码来解析字符串?
-
澄清一下,您要捕获哪个引用:包含整个输入(第一个和最后一个字符)的引用,还是包含内部引用部分的引用?