【问题标题】:How to simplify a regular expression by not re-writing the same capture group?如何通过不重写相同的捕获组来简化正则表达式?
【发布时间】:2019-07-24 03:51:13
【问题描述】:

输入文字:

周一至周五上午 6:00 至晚上 8:00

周六至周日上午 6:30 至晚上 8:00

我需要匹配粗体文本,所以下面的正则表达式:

(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday) (to) (Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)

如何通过避免重写(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday) 捕获组来简化正则表达式?

【问题讨论】:

  • 你在什么引擎中实现这个?
  • 我正在使用 Javascript
  • 您将不得不离开纯正则表达式机制并使用周围语言的功能,例如文本变量中的正则表达式的一部分。这会是一个选择吗?
  • 嗯,是的。我可以let captureGroup = (Monday|Tuesday...)let regex = captureGroup + ' (to) ' + captureGroup 但我正在寻找一个正则表达式机制
  • 如果您不需要单独的捕获,并且模式必须出现在输入的开头,那么您可以这样做^(( to |^)(Monday|Tuesday)){2}

标签: javascript regex


【解决方案1】:

您可以定义一个字符串片段交替,然后重用它:

var input = "Monday to Friday 6:00 a.m. to 8:00 p.m.";
var alt = "(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)";
var re = new RegExp("^" + alt + " (to) " + alt + ".*$");
if (re.test(input)) {
    console.log("valid");
}
else {
    console.log("invalid");
}

【讨论】:

  • 是的,就像我在评论中所说的那样,我正在寻找正则表达式机制。所以如果没有,我会求助于这个
  • like I said 是不正确的英语语法,除非你告诉我你只是说“喜欢”。你的意思是说“就像我说的那样”。
  • LOL 完全无关紧要,但没关系,我一生都在使用这个短语。 macmillandictionary.com/dictionary/british/like-i-say-said
  • ..a 还有这个quodb.com/search/%22like%20i%20said%22 是的,我知道我不能用“and”开始一个句子
  • 你认为有一条规则是禁止以“And”开头的句子吗?正如丘吉尔(据称)所说,"this is the kind of nonsense up with which I will not put"。并且“就像我说的”是完全地道的英语 - 也许有点不正式,但不是不正确的。我对美国人的了解还不够高尚。
【解决方案2】:

如果可以做出以下假设:

  • 比赛结束后,您不需要单独的捕获
  • 模式必须出现在输入的开始

那么你可以这样做:

^\b(( to |^)(Monday|Tuesday)){2}\b

说明

  • ^ 与输入的开头匹配。
  • \b 要求第一个字符是单词字符。它可以防止在字符串的开头匹配“to”。
  • {2} 要求主体部分连续匹配两次
  • ( to |^) 理论上可以匹配“to”或输入的开头,但是自从我们第一次知道我们在开头(因为第一个^),它不能匹配“to”,因为之前的\b,那就是无操作。第二次,它不能再匹配输入的开始,因为我们已经匹配了一天,所以只有“to”可以在第二次迭代中匹配。
  • 最后的\b 是为了避免Tuesdaymorning 这样的东西匹配。

【讨论】:

    【解决方案3】:

    这更短,但也更丑:

    ((?:(?:Mon|Tues|Wednes|Thurs|Fri|Satur|Sun)day)(?: to )?)+
    

    虽然它也匹配Monday Friday 之类的东西(没有to)。

    为了可读性,我自己肯定会使用更大的版本。

    【讨论】:

    • 请注意,这可能会匹配 " to " 两次,如 "Monday to Friday to work"
    【解决方案4】:

    假设您的搜索文本仅包含以下格式的数据: 每天早上 6:00 到晚上 8:00,您可以使用

    re.findall("([A-Za-z]*day)\s(to)\s([A-Za-z]+day)","Monday to Tuesday  6:00 a.m. to 8:00 p.m")
    

    【讨论】:

      猜你喜欢
      • 2016-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-13
      • 2011-03-11
      • 2017-01-07
      • 2019-12-19
      • 1970-01-01
      相关资源
      最近更新 更多