如何在不指定替代项两次的情况下匹配重复模式中的重复模式?

How can I match a repeating pattern within a repeating pattern without specifying the alternatives twice?

假设我有以下字符串,代表一天或多天或日期范围:

mon,thu..fri,sun

如何将任意范围列表或单个日期与正则表达式匹配,而不将日期选项扩展两次

我目前有这个:

(?P<weekdays>
    (                        
        \b
        (mon|tue|wed|thu|fri|sat|sun)
        (\.\.(mon|tue|wed|thu|fri|sat|sun))?
        ,?
    )*
)

... 这行得通,但它迫使我在正则表达式中重复日期替代方案(此处已简化但更长!)。请注意,此正则表达式匹配 fri,sat,,因此可选择以逗号结尾,这是所需的行为。

我也尝试使用 {1,2} 使范围部分成为有限的重复,但我无法避免匹配无效的 mon..tue..fri,因为模式通过可选的逗号重新启动。

请注意,这是更长的正则表达式的一部分,因此我不能使用全局标志。

This is the Regex101 URL,我还添加了一些单元测试。

小修改: 使用了 \b 元字符而不是负先行。

你可以试试这个

/(\bmon\b|\btue\b|\bwed\b|\bthu\b|\bfri\b|\bsat\b|\bsun\b)/g

您可以使用 PCRE 命名组并在以后使用 (?&groupName) 构造重用子模式:

^(?<weekdays>
    (                        
        \b
        (?<weeks>mon|tue|wed|thu|fri|sat|sun)
        (?:\.\.(?&weeks))?
        ,?
    )+
)$

RegEx Demo


要将定义与引用分开,请使用 PCRE 的 DEFINE 指令:

(?(DEFINE)
   (?<weeks>mon|tue|wed|thu|fri|sat|sun)
)
^(?P<weekdays>
    (?:                        
        \b
        (?&weeks)
        (?:\.\.(?&weeks))?
        ,?
    )*
)$

RegEx Demo 2

请注意,对于您要执行的操作,您甚至根本不需要引用捕获组。玩一个单词边界就够了:

\A \b
(?:
    (?: , |  \.\. )?                
    (?: mon|tue|wed|thu|fri|sat|sun) \b
)++
\z

demo