Java Regex-包含多个下划线的单词

Java Regex-包含多个下划线的单词,java,regex,identifier,lexer,Java,Regex,Identifier,Lexer,我正在制作一个Lexer,并选择使用Regex分割我的代币 我正在研究所有不同的标记,除了真正让我讨厌的是单词和标识符 你看,我制定的规则如下: 单词不能以下划线开头或结尾 单词的长度可以是一个或多个字符 下划线只能在字母之间使用,并且可以出现多次 我想要的示例: _foo <- Invalid. foo_ <- Invalid. _foo_ <- Invalid. foo_foo <- Valid. foo_f

我正在制作一个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]+
与一个或多个字母匹配。
模式的第二部分,
(?:[a-zA-Z]+)
,如果后跟一个或多个字母,则与未得分匹配。
末尾的
*
表示第二部分可以重复零次或多次。

(?:)
类似于普通的
()
,但不返回匹配的组

天哪!谢谢你。你能解释一下你有什么不同吗?如果你不使用
String#matches()
,或者你想在更大的文本中查找单词,而不是标识符,这个正则表达式也会匹配
\u foo
中的
foo
。不确定是否为预期值。@frayment模式的第一部分,
[a-zA-Z]+
与一个或多个字母匹配。模式的第二部分,
(?:[a-zA-Z]+)
,如果后跟一个或多个字母,则与未得分匹配。末尾的*表示第二部分可以重复零次或多次。
(?:)
类似于普通的
()
,但不返回匹配的组。@WiktorStribiżew如果您查看问题中的规则,应该可以。除非你说的是被捕获,否则是的,这是不可能的。@frayment:
\u-foo
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;
                    }
                }
            }
        }
    }
}