我正在制作一个词法分析器,选择使用正则表达式来分割我的令牌。
我正在处理各种令牌,唯一困扰我的是单词和标识符。
你看,我现在设定的规则如下:
- 单词不能以或以下划线结尾。
- 单词的长度可以为一个或多个字符。
- 下划线只能在字母之间使用,并且可以出现多次。
以下是我想要的示例:
_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;
}
}
}
}
}
}
String#matches()
,或者您想在更大的文本中查找单词而不是标识符,则此正则表达式也将匹配_foo
中的foo
。不确定这是否符合预期。 - Wiktor Stribiżew[a-zA-Z]+
匹配一个或多个字母。模式的第二部分(?:_[a-zA-Z]+)
匹配下划线,如果它后面跟着一个或多个字母。末尾的 * 表示第二部分可以重复零次或多次。(?: )
类似于普通的()
,但不返回匹配的组。 - RootTwofoo_**foo**
,那么是不被期望的。 - user5549921_foo
<- 无效的。 现在,正则表达式演示在这里。这是否是预期的? - Wiktor Stribiżew