这是我想要解决的具体问题的概括。
给定一串由单个空格分隔的唯一可识别元素:
0 1 2 3 4
如果没有修改字符串,当任何一个数字是可选的,除了一个数字和数字是有序的,那么正则表达式会匹配这个表达式吗?
其他有效字符串的示例:
2
0 4
1 4
0 1 2 3
0 1 3 4
0 1 2 3 4
答案 0 :(得分:3)
正则表达式可能不是最好的工具。如果您可以使用前瞻,那么您可以通过以下示例进行管理:
^(?=0? ?1? ?2? ?3? ?4?$)(?:\d )*\d$
说明:
^ Match the start of line/string. (?=0? ?1? ?2? ?3? ?4?$) Look ahead to restrict to 0 to 4 in that order. (?:\d )*\d Ensure that the string is alternating digit then space. $ Match the end of line/string.
将它概括为固定长度的字符串,所有长度都相等,使得读取起来稍微困难一些。例如,对于ab ba cd de ef
,它将如下所示:
^(?=(?:ab)? ?(?:ba)? ?(?:cd)? ?(?:de)? ?(?:ef)?$)(?:\w{2} )*\w{2}$
但是将它推广到不同长度的单词会变得更加混乱,例如zero one two three four
你可以使用这个正则表达式:
^(?=(?:zero)? ?(?:one)? ?(?:two)? ?(?:three)? ?(?:four)?$)(?! )(?: ?(?:zero|one|two|three|four)(?= |$))+$
答案 1 :(得分:1)
我强烈支持从元模式中编程生成正则表达式模式(另请参阅Martin Fowler's argument for using composed regex)。该技术非常适用于这种情况。
这是Java中的解决方案:
static String orderedOptional(String sep, String... items) {
StringBuilder sb = new StringBuilder();
for (String item : items) {
sb.append(
"(?:item(?:sep(?!$)|$))?"
.replace("item", item)
.replace("sep", sep)
);
}
return sb.toString();
}
static String wholeLineNonEmpty(String pattern) {
return "^(?!$)pattern$".replace("pattern", pattern);
}
现在我们有(as seen on ideone.com):
String PATTERN =
wholeLineNonEmpty(
orderedOptional(" ",
"one", "two", "three")
);
String[] tests = {
"", // false
"onetwo", // false
"one two", // true
"one two ", // false
"two three", // true
"three", // true
"one three", // true
"one two three", // true
"three two one" // false
};
for (String test : tests) {
System.out.println(test.matches(PATTERN));
}
还可以轻松地将orderedOptional
元模式与其他分隔符和项目一起使用,也可以在没有wholeLineNonEmpty
元模式的情况下使用它。这是一个例子:
String INCREASING_DIGITS =
wholeLineNonEmpty(
orderedOptional("[,;]",
"1", "2", "3", "4", "5", "6", "7", "8", "9")
);
System.out.println(INCREASING_DIGITS);
// ^(?!$)(?:1(?:[,;](?!$)|$))?(?:2(?:[,;](?!$)|$))?(?:3(?:[,;](?!$)|$))?
// (?:4(?:[,;](?!$)|$))?(?:5(?:[,;](?!$)|$))?(?:6(?:[,;](?!$)|$))?
// (?:7(?:[,;](?!$)|$))?(?:8(?:[,;](?!$)|$))?(?:9(?:[,;](?!$)|$))?$
此模式接受例如"9"
,"1;2,4"
,"2,3"
并拒绝,例如""
,"4321"
,"4;3;2;1"
,"1;"
(see on rubular.com)。毫无疑问,最终的模式看起来很丑陋,难以理解,但这就是为什么它首先以编程方式生成,使用更容易理解的简单模式和自然自动化的过程。
答案 2 :(得分:0)
没有正则表达式能够验证语言的顺序,除非为可接受的有序集合的每个组合指定表达式。您应该查看pushdown automata解决方案。
答案 3 :(得分:0)
正则表达式不足以解决任意输入字符串的问题。对于任何set输入字符串,您可以通过列出所有可能匹配的字符串来明显构建正则表达式,但这很愚蠢。在任何现代高级语言中,这个问题应该是微不足道的,所以让我们知道你正在使用的语言。