我是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构造中包含的不同值的方法。正则表达式可以做到这一点吗?
答案 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}$
(?!.*([a-z]{2}).*\1)
是一个否定的超前查询,如果字符串中有重复的两个字母的块,则匹配失败。
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
部分。