所以,我需要为家庭作业编写一个编译器扫描仪,并认为它是优雅的"使用正则表达式。事实是,我以前很少使用它们,这是很久以前的事了。所以我忘记了大部分关于它们的东西,需要环顾四周。我成功地使用它们作为标识符(或者至少我认为是这样,我仍然需要做一些进一步的测试,但现在它们看起来都很好),但我对数字识别有问题。
函数nextCh()
读取输入上的下一个字符(lookahead char)。我在这里要做的是检查此字符是否与正则表达式[0-9]*
匹配。我在当前令牌的str
字段中追加每个匹配的字符,然后我读取该字段的int值。它识别单个数字输入,如" 123",但我遇到的问题是输入" 123 456",最终的str将是" 123 456" ;虽然我应该得到2个单独的标记字段" 123"和" 456"。为什么" "匹配?
private void readNumber(Token t) {
t.str = "" + ch; // force conversion char --> String
final Pattern pattern = Pattern.compile("[0-9]*");
nextCh(); // get next char and check if it is a digit
Matcher match = pattern.matcher("" + ch);
while (match.find() && ch != EOF) {
t.str += ch;
nextCh();
match = pattern.matcher("" + ch);
}
t.kind = Kind.number;
try {
int value = Integer.parseInt(t.str);
t.val = value;
} catch(NumberFormatException e) {
error(t, Message.BIG_NUM, t.str);
}
谢谢!
PS:我确实使用下面的代码解决了我的问题。不过,我想了解我的正则表达式中缺陷的位置。
t.str = "" + ch;
nextCh(); // get next char and check if it is a number
while (ch>='0' && ch<='9') {
t.str += ch;
nextCh();
}
t.kind = Kind.number;
try {
int value = Integer.parseInt(t.str);
t.val = value;
} catch(NumberFormatException e) {
error(t, Message.BIG_NUM, t.str);
}
编辑:结果我的正则表达式也不适用于标识符识别(再次,包括空格),所以我不得不切换到类似于我的&#34;解决方案& #34; (虽然有很多条件)。我猜我还需要再次研究正则表达式:O
答案 0 :(得分:2)
我不能100%确定这是否与您的情况相关,但是:
Pattern.compile("[0-9]*");
由于星号,匹配字符串中任何位置的零个或多个数字。我认为空间是匹配的,因为它匹配'零数'。如果你想确保char是一个数字,你必须使用加号匹配一个或多个:
Pattern.compile("[0-9]+");
或者,因为您一次只比较一个字符,所以只需匹配一个号码:
Pattern.compile("^[0-9]$");
答案 1 :(得分:1)
您应该使用matches
方法而不是find
方法。来自文档:
matches方法尝试将整个输入序列与模式匹配
find方法扫描输入序列,寻找与模式匹配的下一个子序列。
换句话说,通过使用find
,如果字符串在任何地方包含数字,您将获得匹配,但如果您使用matches
整个字符串必须与模式匹配。
例如,试试这个:
Pattern p = Pattern.compile("[0-9]*");
Matcher m123abc = p.matcher("123 abc");
System.out.println(m123abc.matches()); // prints false
System.out.println(m123abc.find()); // prints true
答案 2 :(得分:0)
使用更简单的正则表达式
/\d+/
其中
\d
表示数字+
表示一个或多个在代码中:
final Pattern pattern = Pattern.compile("\\d+");