2

我有一个匹配表示 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

4 回答 4

1

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

像这样的东西:

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

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

A op B

意思是

A(BA)*

那么恐怕这种事情是不存在的。 附录:但是,您可以接近

((^|B)A)+$

这转换为“一个或多个 As 以字符串开头或 B 为前缀”。在这里,您的 B 将是逗号,您的 As 将是范围。然后,您可以在范围内使用相同的技术来用冒号分隔单元格。但是,(^|,)您将使用(xxx|:)where代替xxx单元格的开头。我不确定那会是什么。你能用它吗?

附录 2

http://ideone.com/L3RNER上的解决方案 ——基于我最后的评论。

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"));
    }
}
于 2012-11-23T17:01:09.880 回答
1

对于任何一系列范围和单个单元格,请使用正则表达式模式

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

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

^([A-Z]+(?!0)[0-9]+(?::[A-Z]+(?!0)[0-9]+)?)(,\1)*
于 2012-11-23T17:18:12.550 回答
1

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

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

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

(,(?!$)|$)

它匹配一个可选的逗号字符,除非它在匹配的末尾,在这种情况下不能有更多的字符。这可以防止您匹配以逗号结尾的序列。

这是ideone 上的相应演示。

于 2012-11-23T20:28:20.380 回答
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]*)?)*$
于 2012-11-23T18:52:32.117 回答