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

Fin*_*ent 1 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.
Run Code Online (Sandbox Code Playgroud)

我正在接近,因为这是我现在拥有的:

([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;
                    }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Roo*_*Two 5

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

模式的第一部分[a-zA-Z]+匹配一个或多个字母.如果后跟一个或多个字母
,则模式的第二部分(?:_[a-zA-Z]+)匹配非意外核.
所述*在端部装置的第二部分可以重复零次或多次.
(?: )很简单(),但不会返回匹配的组.