0

我有一个关于 Java regex (Pattern, Matcher) 和find(). 我可以解析以下文本吗

Mo, We, Su 10:00 - 22:00

以便第一次调用find()返回以下组

group(1) = Mo
group(2) = 10:00
group(3) = 22:00

的第二次调用find()应该返回

group(1) = We
group(2) = 10:00
group(3) = 22:00

第三次调用find()应该返回

group(1) = Su
group(2) = 10:00
group(3) = 22:00

提前致谢。

4

1 回答 1

3

假设

  • 星期几写为Mo, Tu, We, Th, Fr, Sa, 和Su
  • 时间有效。我将匹配我的正则表达式中的任何数字序列。

解决方案

您可以使用此正则表达式(我允许间距灵活):

(Mo|Tu|We|Th|Fr|Sa|Su)(?=(?: *+, *+(?:Mo|Tu|We|Th|Fr|Sa|Su))* *+(\d+:\d+) *+- *+(\d+:\d+))

上面的正则表达式非常严格——如果逗号分隔的列表包含当前星期几到时间范围之间的其他内容(例如Su, Somethingelse 02:12 - 3:45),它将不会产生匹配。

如果您完全确定字符串的格式是正确的,并且您只想提取数据,那么这个松散的正则表达式就足够了:

([a-zA-Z]+)(?=\D+(\d+:\d+)\D+(\d+:\d+))

将它们放入字符串文字中:

"(Mo|Tu|We|Th|Fr|Sa|Su)(?=(?: *+, *+(?:Mo|Tu|We|Th|Fr|Sa|Su))* *+(\\d+:\\d+) *+- *+(\\d+:\\d+))"
"([a-zA-Z]+)(?=\\D+(\\d+:\\d+)\\D+(\\d+:\\d+))"

解释

(Mo|Tu|We|Th|Fr|Sa|Su)(?=(?: *+, *+(?:Mo|Tu|We|Th|Fr|Sa|Su))* *+(\d+:\d+) *+- *+(\d+:\d+))
  • (Mo|Tu|We|Th|Fr|Sa|Su):匹配一周中的某一天。

  • (?=(?: *+, *+(?:Mo|Tu|We|Th|Fr|Sa|Su))* *+(\d+:\d+) *+- *+(\d+:\d+)):一个零宽度(文本不会被消耗)正向前瞻(如果里面的模式匹配,那么它可以继续;否则,匹配失败并回溯)。它由 指定(?=pattern)

    里面的图案是(?: *+, *+(?:Mo|Tu|We|Th|Fr|Sa|Su))* *+(\d+:\d+) *+- *+(\d+:\d+)。在这里,我们试图匹配当前星期几之后的文本部分,并捕获时间。

    • (?: *+, *+(?:Mo|Tu|We|Th|Fr|Sa|Su))* *+: 在星期几之后,我们可以用逗号分隔其他星期几。

    • (\d+:\d+) *+- *+(\d+:\d+): 然后是时间范围。

    • 您可以看到一些 *+(空格、星号、加号)序列。 *表示匹配 0 个或多个*空格字符,贪婪地,但是允许回溯。 *+所有格,这意味着它不允许回溯。您可以将其视为一种优化,以防止完成不必要的工作。


([a-zA-Z]+)(?=\D+(\d+:\d+)\D+(\d+:\d+))

对于这个,我假设星期几是输入字符串中唯一的字母字符序列。我还假设时间戳是唯一可以有数字的地方。

于 2013-02-11T13:25:08.800 回答