如何强制匹配重复n次的OR构造中的其他字符串

时间:2018-07-08 17:58:17

标签: java regex

我是regex的新手,我正在尝试验证用户输入的字段是否以逗号分隔的格式输入周末,并且该日使用2个字符的缩写。我开发了以下无法正常运行的模式:

  

^(fr | sa | su | mo | tu | we | th)?(?(1)(,fr |,sa |,su |,mo |,tu |,we |,th)){0 ,5} $

此模式成功匹配所需的输入,如下所示:

fr

mo

fr,sa

fr,tu

su,mo,tu,we,fr,sa

但它也与以下错误的输入项匹配:

fr,fr,fr,fr

sa,sa,sa,sa

我想要一种强制第二组仅重复OR构造中包含的不同值的方法。正则表达式可以做到这一点吗?

1 个答案:

答案 0 :(得分:1)

您可以在正则表达式的开头使用(?!.*([a-z]{2}).*\1)否定的前瞻,以禁止在字符串中重复2个字母的值(由于字符串格式,您甚至不需要在前瞻中进行单词边界或逗号上下文检查):

^(?!.*([a-z]{2}).*\1)(fr|sa|su|mo|tu|we|th)?(?:,(?:fr|sa|su|mo|tu|we|th)){0,5}$

请参见enter image description here

(?!.*([a-z]{2}).*\1)是一个否定的超前查询,如果字符串中有重复的两个字母的块,则匹配失败。

regex demo

String day = "fr|sa|su|mo|tu|we|th";
String pattern = "(?!.*([a-z]{2}).*\\1)(?:" + day + ")?(?:,(?:" + day + ")){0,5}";
if (s.matches(pattern)) {
    System.out.println("Valid!");
} else {
    System.out.println("Invalid!");
}

请注意,String#matches需要完整的字符串匹配,因此不需要^$

请注意,您可以使用字符类day => fr|sa|su|mo|tu|we|th缩短fr|s[au]|mo|t[uh]|we部分。