Java 用“查找文本的部分”;查找“;

Java 用“查找文本的部分”;查找“;,java,regex,Java,Regex,我有一个关于Java正则表达式(模式、匹配器)和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 group(1) = Su group(2) = 10:00 group(3) = 2

我有一个关于Java正则表达式(模式、匹配器)和
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
group(1) = Su
group(2) = 10:00
group(3) = 22:00
第三次调用
find()
应该返回

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

提前感谢。

假设

  • 一周中的天数写为
    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+)
    :零宽度(文本不会被消耗)正向前瞻(如果匹配中的模式可以继续;否则,匹配失败并返回)。它由
    (?=模式)
    指定

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

    • (?:*+,*+(?:Mo | Tu | We | Th | Fr | Sa | Su))***+
      :在一周中的某一天之后,我们可以用逗号分隔另一周中的某一天

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

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



对于本例,我假设一周中的几天是输入字符串中唯一的字母序列。我还假设时间戳是唯一可以有数字的地方。

假设

  • 一周中的天数写为
    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+)
    :零宽度(文本不会被消耗)正向前瞻(如果匹配中的模式可以继续;否则,匹配失败并返回)。它由
    (?=模式)
    指定

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

    • (?:*+,*+(?:Mo | Tu | We | Th | Fr | Sa | Su))***+
      :在一周中的某一天之后,我们可以用逗号分隔另一周中的某一天

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

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



对于本例,我假设一周中的几天是输入字符串中唯一的字母序列。我还假设时间戳是唯一可以有数字的地方。

向前看就是我要找的。非常感谢。前瞻性是我一直在寻找的。谢谢。