【发布时间】:2020-02-25 15:52:46
【问题描述】:
我正在尝试使用java.util.Scanner 来标记算术表达式,其中分隔符可以是:
- 空白(
\s+或\p{Space}+),应丢弃 - 标点符号 (
\p{Punct}),应作为标记返回
示例
给定这个表达式:
12 + (ab-bc*3)
我希望 Scanner 返回这些令牌:
12+(ab-bc*3)
代码
到目前为止,我只能:
- 吃掉所有的标点符号(不是我想要的):
new Scanner("12 + (ab-bc*3)").useDelimiter("\\p{Space}+|\\p{Punct}").tokens().collect(Collectors.toList())- 结果:
"12", "", "", "", "ab", "bc", "3"
- 使用positive lookahead 取得部分成功
new Scanner("12 + (ab-bc*3)").useDelimiter("\\p{Space}+|(?=\\p{Punct})").tokens().collect(Collectors.toList())- 结果:
"12", "+", "(ab", "-bc", "*3", ")"
但现在我被困住了。
【问题讨论】:
-
你可以使用
"\\p{Punct}|\\w+"正则表达式匹配它们 -
不幸的是,这个正则表达式吃掉了我所有的令牌:
new Scanner("12 + (ab-bc*3)").useDelimiter("\\p{Punct}|\\w+").tokens()只返回空字符串 -
我说匹配它们,在扫描仪中,你用模式分割。见Java demo。
-
我会说你不会得到你想要的,因为你试图只指定你想要的分隔符类型,但你从来没有说你想要什么样的标记。就扫描仪而言,
"-bc"中没有分隔符,我认为没有任何可能的配置可以改变它(从技术上讲,其中的分隔符是一个“空字符”,这实际上不是一个东西)。你需要说出你想要什么样的令牌,通过使用适当的正则表达式将.token()更改为.findAll,就像 Wiktor 建议的那样。 -
@DaniloPiazzalunga,您可能希望将模式保存在实际应用中的某个位置,而不是继续为同一事物创建和解析正则表达式。
标签: java regex java.util.scanner delimiter