正则表达式意外模式匹配
Regular expression unexpected pattern matching
我正在尝试使用 C-Bison 和 Flex 创建一个语法分析器。在 Flex 中,我有一个正则表达式,它根据以下内容匹配整数:
Must start with any digit in range 1-9 and followed by any number of digits in range 0-9. (ex. Correct: 1,12,11024 | Incorrect: 012)
Can be signed (ex. +2,-5)
The number 0 must not be followed by any digit (0-9) and must not signed. (ex. Correct: 0 | Incorrect: 012,+0,-0)
这是我创建的用于执行匹配的正则表达式:
[^+-]0[^0-9]|[+-]?[1-9][0-9]*
这是我正在测试的表达式:
(1 + 1 + 10)
比赛:
1
1
10)
这是我的问题,为什么它匹配'10)'?
我使用上面的表达式而不是更简单的表达式的原因,
(0|[+-]?[1-9][0-9]*) 是由于解析器无法识别不正确的表达式,例如 012。
问题似乎仅在“)”之前出现在数字“0”之前。但是,如果“0”前面有两位或更多数字(例如 100),则“)”不匹配。
我知道如果我从正则表达式中删除 [^0-9] 它与 ')' 不匹配。
匹配10(
,因为1
匹配[^+-]
,0
匹配0
,(
匹配[^0-9]
。
The reason I used the above expression, instead of the much simpler one, (0|[+-]?[1-9][0-9]*) is due to inability of the parser to recognise incorrect expressions such as 012.
怎么会这样?使用上面的正则表达式,012
将被识别为两个标记:0
和 12
。这不会导致您的解析器出错吗?
诚然,这不会产生很好的错误消息,因此更好的方法可能是只使用 [0-9]+
作为正则表达式,然后使用操作来检查前导零。这样 012
将是单个标记,词法分析器可能会产生有关前导零的错误或警告(我在这里假设您实际上想要禁止前导零 - 不要将它们用于八进制文字)。
除了在操作中检查,您还可以保留正则表达式,然后为带前导零的整数添加另一个正则表达式(如 0[0-9]+ { warn("Leading zero"); return INT; }
),但我会在操作中进行检查因为这是一个简单的检查,它使正则表达式简短。
PS:如果将 -
和 +
作为整数标记的一部分,则 2+3
之类的东西将被视为整数 2
,后跟整数 +3
,而不是整数 2
和 3
,中间有一个 +
标记。因此,通常最好不要让符号成为整数标记的一部分,而是在解析器中允许使用前缀 +
和 -
运算符。
我正在尝试使用 C-Bison 和 Flex 创建一个语法分析器。在 Flex 中,我有一个正则表达式,它根据以下内容匹配整数:
Must start with any digit in range 1-9 and followed by any number of digits in range 0-9. (ex. Correct: 1,12,11024 | Incorrect: 012)
Can be signed (ex. +2,-5)
The number 0 must not be followed by any digit (0-9) and must not signed. (ex. Correct: 0 | Incorrect: 012,+0,-0)
这是我创建的用于执行匹配的正则表达式: [^+-]0[^0-9]|[+-]?[1-9][0-9]*
这是我正在测试的表达式: (1 + 1 + 10)
比赛:
1
1
10)
这是我的问题,为什么它匹配'10)'?
我使用上面的表达式而不是更简单的表达式的原因, (0|[+-]?[1-9][0-9]*) 是由于解析器无法识别不正确的表达式,例如 012。
问题似乎仅在“)”之前出现在数字“0”之前。但是,如果“0”前面有两位或更多数字(例如 100),则“)”不匹配。
我知道如果我从正则表达式中删除 [^0-9] 它与 ')' 不匹配。
匹配10(
,因为1
匹配[^+-]
,0
匹配0
,(
匹配[^0-9]
。
The reason I used the above expression, instead of the much simpler one, (0|[+-]?[1-9][0-9]*) is due to inability of the parser to recognise incorrect expressions such as 012.
怎么会这样?使用上面的正则表达式,012
将被识别为两个标记:0
和 12
。这不会导致您的解析器出错吗?
诚然,这不会产生很好的错误消息,因此更好的方法可能是只使用 [0-9]+
作为正则表达式,然后使用操作来检查前导零。这样 012
将是单个标记,词法分析器可能会产生有关前导零的错误或警告(我在这里假设您实际上想要禁止前导零 - 不要将它们用于八进制文字)。
除了在操作中检查,您还可以保留正则表达式,然后为带前导零的整数添加另一个正则表达式(如 0[0-9]+ { warn("Leading zero"); return INT; }
),但我会在操作中进行检查因为这是一个简单的检查,它使正则表达式简短。
PS:如果将 -
和 +
作为整数标记的一部分,则 2+3
之类的东西将被视为整数 2
,后跟整数 +3
,而不是整数 2
和 3
,中间有一个 +
标记。因此,通常最好不要让符号成为整数标记的一部分,而是在解析器中允许使用前缀 +
和 -
运算符。