我非常确定这是一个简单的解决方案,但是我已经搜索了三个小时,却没有找到任何可以帮助我的东西。
我正在使用regex用Java编写解析器,并且应该能够匹配一些先前确定的单词,1-10000的数字和十六进制颜色代码。现在,与单词匹配非常好,但是读者并没有整体阅读数字和颜色代码。例如,它读取输入:
下。颜色#000000。
如:
阅读:DOWN返回:DOWN
阅读: 。返回:点
阅读:返回:空格
阅读:颜色返回:颜色
阅读:返回:空格
阅读:#返回:没有
阅读:0返回:数字
阅读:返回:没有
阅读:F返回:无
阅读:2返回:数字
阅读:3返回:数字
阅读:4返回:数字
阅读: 。返回:点
因此,它可以按我的要求读取整个颜色和向下,但不读取颜色代码#000000。理想情况下,我希望这七行是:
阅读:#0AF234返回:颜色代码
我有:
String stringTokens = "DOWN|COLOR|(\\s|\\t)+|\\n|\b[1-9][0-9]{0,3}\b|10000|^(#)([a-fA-F0-9]{6})$";
Pattern stringPattern = Pattern.compile(stringTokens, Pattern.CASE_INSENSITIVE);
Matcher m = stringPattern.matcher(input);
然后:
while (m.find()) {
if (m.start() != inputPos) {
tokens.add(new Token(lineNo, TokenType.Invalid));
}
if (m.group().matches("^(#)([a-fA-F0-9]{6})$"))
tokens.add(new Token(lineNo, TokenType.ColorCode));
else if (m.group().equals("."))
tokens.add(new Token(lineNo, TokenType.Dot));
else if (m.group().matches("DOWN"))
tokens.add(new Token(lineNo, TokenType.Down));
else if (m.group().matches("COLOR"))
tokens.add(new Token(lineNo, TokenType.Color));
else if (Character.isDigit(m.group().charAt(0)))
tokens.add(new Token(lineNo, TokenType.Number, Integer.parseInt(m.group())));
else if (m.group().matches("\\n")) {
tokens.add(new Token(lineNo, TokenType.Whitespace));
lineNo++;
}
else if (m.group().matches("(\\s|\\t)+"))
tokens.add(new Token(lineNo, TokenType.Whitespace));
inputPos = m.end();
}
所以我的问题基本上是:
我如何一起阅读有关颜色代码和数字的组?当我现在为每个读数打印m.group()时,它只返回一位数字。但是我正在看另一个以相同格式读取数字的代码,上面的正则表达式只是[0-9] +,这对我来说太简单了。然后将每个组读取为整数。
我试图使用类似于m.group(1)和m.group(2)的东西,使用了边界(我不完全理解)和^ $格式,但似乎没有任何作用整个令牌。
我希望我设法使复制的代码简单而不丢失任何重要内容,并且希望有人可以帮助我弄清楚这一点(一定是?!)。谢谢! :)
最佳答案
所以你有一个正则表达式:
DOWN|COLOR|(\\s|\\t)+|\\n|\b[1-9][0-9]{0,3}\b|10000|^(#)([a-fA-F0-9]{6})$
我们可以分解为:
DOWN
COLOR
(\\s|\\t)++
:一个或多个\ s(好的,这是一个空格类)或\ t(因为\ s中包含了\ t,所以实际上不需要)\\n
(请注意,这也包含在\ s中)\b[1-9][0-9]{0,3}\b
:好的,在这里您尝试使用单词边界,但是您没有考虑到反斜杠需要在Java字符串中转义,因此应为\\b
。不知道为什么要使用它?10000
:这不是以前的模式所涵盖的吗?^(#)([a-fA-F0-9]{6})$
:(#)似乎不必要,只需#。使用^ ... $,您将只强制输入内容为#abcdabcd,因此我将其删除。您如何匹配圆点?
由于您需要再次进行匹配以区分不同类型的令牌,因此,为什么不使用多个正则表达式(每个令牌一个)(或完全不使用正则表达式),就可以对照要解析的字符串的头部进行检查。
如果匹配,则您有一个新令牌,并且可以使用字符串的匹配部分。