正则表达式 - 包含多个下划线的单词

4

我正在制作一个词法分析器,选择使用正则表达式来分割我的令牌。

我正在处理各种令牌,唯一困扰我的是单词和标识符

你看,我现在设定的规则如下:

  • 单词不能以或以下划线结尾。
  • 单词的长度可以为一个或多个字符。
  • 下划线只能在字母之间使用,并且可以出现多次。

以下是我想要的示例:

_foo         <- Invalid.
foo_         <- Invalid.
_foo_        <- Invalid.
foo_foo      <- Valid.
foo_foo_foo  <- Valid.
foo_foo_     <- Partially Valid. Only "foo_foo" should be picked up.
_foo_foo     <- Partially Valid. Only "foo_foo" should be picked up.

我离目标很近了,这是我目前拥有的内容: ([a-zA-Z]+_[a-zA-Z]+|[a-zA-Z]+) 但是它只能检测到下划线的第一次出现。我想要所有下划线的匹配。
个人请求: 我希望答案包含在一个单独的组中,因为我已经围绕它们构建了我的分词器,但如果您能想到更好的处理方式,我也会非常乐意更改我的设计。这是我目前使用的内容:
private void tokenise(String regex, String[] data) {
    Set<String> tokens = new LinkedHashSet<String>();
    Pattern pattern = Pattern.compile(regex);
    // First pass. Uses regular expressions to split data and catalog token types.
    for (String line : data) {
        Matcher matcher = pattern.matcher(line);
        while (matcher.find()) {
            for (int i = 1; i < matcher.groupCount() + 1; i++) {
                if (matcher.group(i) != null) {
                    switch(i) {
                    case (1):
                        // Example group.
                        // Normally I would structure like:
                        // 0: Identifiers
                        // 1: Strings
                        // 2-?: So on so forth.
                        tokens.add("FOO:" + matcher.group());
                        break;
                    }
                }
            }
        }
    }
}
1个回答

12

尝试([a-zA-Z]+(?:_[a-zA-Z]+)*)

模式的第一部分[a-zA-Z]+匹配一个或多个字母。
模式的第二部分(?:_[a-zA-Z]+)匹配下划线,如果它后面跟着一个或多个字母。
末尾的*表示第二部分可以重复零次或多次。
(?: )像普通的()一样,但不返回匹配的组。


1
哦,我的天啊!谢谢你。你能否请解释一下你做了什么不同的事情? - user5549921
如果您不使用String#matches(),或者您想在更大的文本中查找单词而不是标识符,则此正则表达式也将匹配_foo中的foo。不确定这是否符合预期。 - Wiktor Stribiżew
@frayment 此模式的第一部分 [a-zA-Z]+ 匹配一个或多个字母。模式的第二部分 (?:_[a-zA-Z]+) 匹配下划线,如果它后面跟着一个或多个字母。末尾的 * 表示第二部分可以重复零次或多次。(?: ) 类似于普通的 (),但不返回匹配的组。 - RootTwo
如果您查看问题中的规则,那应该是可以的。除非您在谈论捕获 foo_**foo**,那么是不被期望的。 - user5549921
@frayment: _foo <- 无效的。 现在,正则表达式演示在这里。这是否是预期的? - Wiktor Stribiżew
@WiktorStribiżew 没问题,这很好。它像预期的那样忽略下划线。我正在做的是,任何未被检测到的内容都会被冲入"语法错误"捕获组中。 - user5549921

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接