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

时间:2016-02-03 06:20:04

标签: java regex identifier lexer

我正在制作一个Lexer,并选择使用正则表达式来分割我的代币。

我正在处理所有不同的令牌,除了真正让我感到困惑的是单词和标识符

你知道,我现有的规则如下:

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

我想要的例子:

_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]+)

除此之外,它仅检测下划线的第一次出现。我想要所有这些。

个人要求:

我希望答案能够包含在一个组中,因为我已经围绕它们构建了我的tokeniser,除非我能够更好地改变我的设计,如果你能想到更好的处理方式。这就是我目前使用的:

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 个答案:

答案 0 :(得分:5)

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

模式的第一部分[a-zA-Z]+匹配一个或多个字母 如果后跟一个或多个字母,则模式的第二部分(?:_[a-zA-Z]+)与非核心匹配 最后*表示第二部分可以重复零次或多次 (?: )与普通()类似,但不会返回匹配的组。