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

Regex - Words containing multiple underscores

我正在制作 Lexer,并选择使用 Regex 来拆分我的标记。

我正在研究所有不同的标记,除了真正让我烦恼的是 单词和标识符

你看,我制定的规则如下:

我想要的例子:

_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;
                    }
                }
            }
        }
    }
}

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

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