我想构建一个匹配'
或"
的正则表达式,然后匹配其他字符,分别在'
或"
匹配时结束,具体取决于在开始时遇到的问题。所以这个问题看起来很简单,最后可以通过反向引用来解决;下面是一些正则表达式代码(它是用Java编写的,所以请注意额外的转义字符,例如\
之前的"
:
private static String seekerTwo = "(['\"])([a-zA-Z])([a-zA-Z0-9():;/`\\=\\.\\,\\- ]+)(\\1)";
此代码将成功处理以下内容:
"hello my name is bob"
'i live in bethnal green'
当我有这样的字符串时出现问题:
"hello this seat 'may be taken' already"
使用上面的正则表达式会在遇到'
时在初始部分失败然后它会继续并成功匹配'may be taken'
...但这显然是不够的,我需要整个字符串是匹配。
我在想的是,我需要一种方法来忽略引号的类型,它在第一组中不匹配,将它包含在第3组字符集中的字符中。但是,我知道无法做到这一点。是否存在某种偷偷摸摸的非反向引用功能?我可以用来引用第一组中不匹配的角色?或者以某种方式解决我的困境?
答案 0 :(得分:12)
这可以使用否定lookahead assertions来完成。以下解决方案甚至考虑到您可以在字符串中转义引号:
(["'])(?:\\.|(?!\1).)*\1
<强>解释强>
(["']) # Match and remember a quote.
(?: # Either match...
\\. # an escaped character
| # or
(?!\1) # (unless that character is identical to the quote character in \1)
. # any character
)* # any number of times.
\1 # Match the corresponding quote.
这正确匹配"hello this seat 'may be taken' already"
或"hello this seat \"may be taken\" already"
。
在Java中,包含所有反斜杠:
Pattern regex = Pattern.compile(
"([\"']) # Match and remember a quote.\n" +
"(?: # Either match...\n" +
" \\\\. # an escaped character\n" +
"| # or\n" +
" (?!\\1) # (unless that character is identical to the matched quote char)\n" +
" . # any character\n" +
")* # any number of times.\n" +
"\\1 # Match the corresponding quote",
Pattern.COMMENTS);
答案 1 :(得分:2)
"(\\"|[^"])*"|'(\\'|[^'])*'
分别匹配每个案例,但返回任一案例作为整个匹配
<强>无论其强>
这两种情况都可能成为至少一种可能性的牺牲品。如果你不仔细观察,你可能会认为在这段摘录中应该有两个匹配:
他转身骑上自行车。 “我以后会见到你,当我完成所有这些时”他说,在开始他的旅程之前回头看了一会儿。当他进入街道时,一辆城市的手推车与迈克的自行车相撞。 “天啊!”旁观者喊道。
...但是有三个匹配,而不是两个:
"I'll see you later, when I'm done with all this"
's trolleys collided with Mike'
"Oh my!"
此摘录仅包含 ONE 匹配:
但是,战斗尚未结束。 “嘿!”鲍勃喊道。 “你想要什么?”我反驳道。 “你让我恶心!” “我为什么要关心?” “因为我爱你!” “你做?”鲍勃停顿了一会儿,然后低声说道:“不,我不能爱你!”你能找到那个吗? :d
't over yet, though. "Hey!" yelled Bob. "What do you want?" I retorted. "I hate your guts!" "Why would I care?" "Because I love you!" "You do?" Bob paused for a moment before whispering "No, I couldn'
我建议(如果你想使用环视),你考虑做一些额外的检查(例如在第一个引用之前为空格或类似的正面观察),以确保你不匹配像{{ 1}} - 虽然没有先进行大量测试,但我不会在任何解决方案上投入太多资金。将's trolleys collided with Mike'
添加到任一表达式的开头将避免上述情况......即:
(?<=\s|^)
或
(?<=\s|^)(["'])(?:\\.|(?!\1).)*\1 #based on Tim's
我不确定外观与非外观相比有多高效,所以上面两个可能是等价的,或者一个可能比另一个更有效(?)