正则表达式;反向引用字符集中不匹配的字符

时间:2012-03-15 11:03:43

标签: java regex logic backreference

我想构建一个匹配'"的正则表达式,然后匹配其他字符,分别在'"匹配时结束,具体取决于在开始时遇到的问题。所以这个问题看起来很简单,最后可以通过反向引用来解决;下面是一些正则表达式代码(它是用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组字符集中的字符中。但是,我知道无法做到这一点。是否存在某种偷偷摸摸的非反向引用功能?我可以用来引用第一组中不匹配的角色?或者以某种方式解决我的困境?

2 个答案:

答案 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)

如果你可以使用lookaround(Java确实支持),Tim的解决方案可以很好地工作。但如果您发现自己使用的语言或工具不支持环视,则可以单独匹配两种情况(双引号字符串和单引号字符串):

"(\\"|[^"])*"|'(\\'|[^'])*'

分别匹配每个案例,但返回任一案例作为整个匹配


<强>无论其

这两种情况都可能成为至少一种可能性的牺牲品。如果你不仔细观察,你可能会认为在这段摘录中应该有两个匹配:

  他转身骑上自行车。 “我以后会见到你,当我完成所有这些时”他说,在开始他的旅程之前回头看了一会儿。当他进入街道时,一辆城市的手推车与迈克的自行车相撞。 “天啊!”旁观者喊道。

...但是有三个匹配,而不是两个:

"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

我不确定外观与非外观相比有多高效,所以上面两个可能是等价的,或者一个可能比另一个更有效(?)