匹配正则表达式中逗号分隔的组(模式中没有冗余)

时间:2012-11-23 16:54:06

标签: .net regex

我有一个正则表达式,它匹配代表Excel范围的字符串(加上单个单元格)

^[A-Z]+[1-9][0-9]*(:[A-Z]+[1-9][0-9]*)?(,[A-Z]+[1-9][0-9]*(:[A-Z]+[1-9][0-9]*)?)*$

它匹配,例如,字符串:

C5:H6,J5:P6,R5:DM6,C15

我在问是否有办法避免模式中的冗余:

C6[A-Z]+[1-9][0-9]*匹配,但H6也匹配相同的模式。

同样,J6:P6与匹配C6:H6的相同模式匹配。

如果想要表达类似“匹配此模式1次,或*次,但仅限逗号分隔

提前致谢!

4 个答案:

答案 0 :(得分:1)

要删除源代码中的冗余,可以将重复的组件存储到字符串变量中,并从字符串构造正则表达式。

这样的事情:

string cellname = "[A-Z]+[1-9][0-9]*";
string cellrange = cellname + "(:" + cellname + ")?";
Regex pattern = new Regex("^" + cellrange + "(," + cellrange + ")*$")

如果你问是否有分隔符的二进制正则表达式运算符,即你可以编写的东西

A op B

并且意味着

A(BA)*
然后我害怕这样的事情不存在。 ADDENDUM :但是,你可以接近

((^|B)A)+$

这转换为“一个或多个以字符串的开头或B为前缀的As”。在这里你的B将是逗号而你的As将是范围。然后,您可以在范围内使用相同的技术,以使用冒号分隔细胞。但是(^|,)代替(xxx|:),您将xxx使用using System; using System.Text.RegularExpressions; public class Test { public static void Main() { Regex rx = new Regex("^([A-Z]+[1-9][0-9]*(:[A-Z]+[1-9][0-9]*)?($|,(?!$)))*$"); Console.WriteLine(rx.IsMatch("C5:H6")); Console.WriteLine(rx.IsMatch("C5")); Console.WriteLine(rx.IsMatch("C5:H6,J5:P6,R5:DM6,C15")); Console.WriteLine(rx.IsMatch("C5:H6,J5:P6,R5:DM6,C15,")); Console.WriteLine(rx.IsMatch("C5:H6J5:P6,R5:DM6,C15")); Console.WriteLine(rx.IsMatch(",C5:H6:J5:P6,R5:DM6,C15")); } } 扮演单元格开头的角色。我不确定那会是什么。你可以用它吗?

ADDENDUM 2

http://ideone.com/L3RNEr处的解决方案 - 基于我上次的评论。

{{1}}

答案 1 :(得分:1)

对于任何系列的范围和单个单元格都使用正则表达式

(?!,)(?:(?:^|,)[A-Z]+(?!0)[0-9]+(?::[A-Z]+(?!0)[0-9]+)?)+

或者如果您只想匹配用逗号分隔的系列相同范围(或单个单元格),那么

^([A-Z]+(?!0)[0-9]+(?::[A-Z]+(?!0)[0-9]+)?)(,\1)*

答案 2 :(得分:1)

您可以按如下方式更改正则表达式:

^([A-Z]+[1-9][0-9]*(:[A-Z]+[1-9][0-9]*)?(,(?!$)|$))*$

关键变化是最后的这个子表达式:

(,(?!$)|$)

它匹配一个可选的逗号字符,除非它在匹配结束时,在这种情况下必须没有其他字符。这可以防止您匹配以悬挂逗号结尾的序列。

以下是相应的demo on ideone

答案 3 :(得分:0)

如果你想在一个表达式中测试整个字符串的有效范围,你可以使用这个正则表达式,如果你不介意用逗号为测试字符串加前缀(如下所示:,C5:H6,J5:P6,R5 :DM6,C15):

^(?:,[A-Z]+[1-9][0-9]*(?::[A-Z]+[1-9][0-9]*)?)*$

如果您无法更改测试字符串,则可以改为使用:

^(?:(?:^|,)[A-Z]+[1-9][0-9]*(?::[A-Z]+[1-9][0-9]*)?)*$