5

所以,我需要为作业编写一个编译器扫描程序,并认为使用正则表达式会很“优雅”。事实上,我以前很少使用它们,而且是很久以前的事了。所以我忘记了大部分关于他们的东西,需要四处看看。我成功地将它们用于标识符(或者至少我认为是这样,我仍然需要做一些进一步的测试,但现在它们看起来都不错),但是我在数字识别方面遇到了问题。

该函数nextCh()读取输入中的下一个字符(前瞻字符)。我想在这里做的是检查这个 char 是否与 regex 匹配[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);           
    }

编辑:原来我的正则表达式也不适用于标识符识别(同样,包括空白),所以我不得不切换到类似于我的“解决方案”的系统(虽然有很多条件)。猜猜我需要再次研究正则表达式:O

4

3 回答 3

2

我不是 100% 确定这是否与您的情况相关,但是:

Pattern.compile("[0-9]*");

由于星号,匹配字符串中任意位置的零个或多个数字。我认为空间匹配,因为它匹配“零数字”。如果您想确保 char 是一个数字,则必须使用加号匹配一个或多个

Pattern.compile("[0-9]+");

或者,因为您一次只比较一个字符,所以只匹配一个数字:

Pattern.compile("^[0-9]$");
于 2012-10-15T01:13:25.130 回答
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
于 2012-10-15T13:20:26.333 回答
0

使用更简单的正则表达式,例如

/\d+/

在哪里

  • \d表示一个数字
  • +表示一个或多个

在代码中:

final Pattern pattern = Pattern.compile("\\d+");
于 2012-10-15T01:15:54.090 回答