我目前正在编写一个库,我希望用户能够在四种可能的替代方案中指定电子表格单元格:
"A1"
; "A1:B10"
"A1,B6,I60,AA2"
"B2:B12,C13:C18,D4,E11000"
然后,为了验证输入是否遵循这些格式,我打算使用正则表达式来匹配。我在维基百科上查阅过这篇文章:
Regular Expression (Wikipedia)
我也发现了这个相关的问题:
regex matching alpha character followed by 4 alphanumerics.
根据上述链接文章中提供的信息,我会尝试使用此正则表达式:
Default Readonly Property Cells(ByVal cellsAddresses As String) As ReadOnlyDictionary(Of String, ICell)
Get
Dim validAddresses As Regex = New Regex("A-Za-z0-9:,A-Za-z0-9")
If (Not validAddresses.IsMatch(cellsAddresses)) then _
Throw New FormatException("cellsAddresses")
// Proceed with getting the cells from the Interop here...
End Get
End Property
问题
1。我的正则表达是否正确?如果没有,请帮助我理解我可以使用的表达方式。
2。 FormatException
和InvalidExpressionException
之间更有意义的例外更有意义吗?我在这里犹豫不决,因为它与属性期望输入单元格的格式有关除此之外,我正在使用(常规)表达来匹配。
非常感谢您的帮助和支持! =)
答案 0 :(得分:4)
我会尝试这个:
[A-Za-z]+[0-9]+([:,][A-Za-z]+[0-9]+)*
说明:
( )
可用于定义组因此,[A-Za-z]+[0-9]+
匹配一个或多个字母,后跟单个单元格地址的一个或多个数字
然后,相同的块重复零次或多次,用','或':'分隔地址。
答案 1 :(得分:3)
假设电子表格的列是任意1或2个字母的值而行是任何正数,则更复杂但更严格的答案仍然是:
^[A-Z]{1,2}[1-9]\d*(:[A-Z]{1,2}[1-9]\d*)?(,[A-Z]{1,2}[1-9]\d*(:[A-Z]{1,2}[1-9]\d*)?)*$
“[A-Z] {1,2} [1-9] \ d *”是单个细胞参考的表达。如果在上面替换“[A-Z] {1,2} [1-9] \ d *”,则表达式为复数
^<cell>(:<cell>)?(,<cell>(:<cell>*)?)*$
更清楚地表明它是一个单元格或一个范围,后跟一个或多个“单元格或范围”条目,其间有逗号。
行和列指标可以进一步细化,以提供更紧密,更复杂的表达。我怀疑上面的内容可以通过前瞻或后面的断言进行简化,但我承认这些都不是我的强项。
答案 2 :(得分:3)
我认为我应该选择这个:
(([A-Z]+[1-9]\d*:)?[A-Z]+[1-9]\d*,)*([A-Z]+[1-9]\d*:)?[A-Z]+[1-9]\d*
这只允许使用大写字母作为前缀。如果您想要不区分大小写,请使用RegexOptions.IgnoreCase。
您可以将[A-Z]+[1-9]\d*
替换为普通旧[A-Z]\d+
来简化此操作,但这只会允许使用单字母前缀,并且还允许A0
和{{1}之类的内容}。由你决定。
编辑:
仔细考虑 DocMax 提及外观,并使用 Hans Kesting 的答案作为灵感,我发现这个应该工作:
B01
或者如果你想要真的扭曲的话:
^[A-Z]+\d+((,|(?<!:\w*):)[A-Z]+\d+)*$
与上一个示例一样,如果要阻止前导零,请将^([A-Z]+\d+(,|$|(?<!:\w*):))*(?<!,|:)
替换为\d+
。
[1-9]\d*
背后的想法是,如果一个组用逗号分隔,你想让它通过;但如果它是冒号,只有在上一个分隔符不是冒号时才允许冒号。 ,|(?<!\w*:):
版本很疯狂,但它允许您只使用一个(,|$|...)
块来完成所有操作。
然而!虽然这个时间更短了,但我承认我觉得它有点聪明,我很遗憾这位可怜的家伙必须来从现在起六个月后继续维持。从代码 - 高尔夫的角度来看,这很有趣,但我认为最好的实际用途是使用早期版本,这样更容易阅读。
答案 3 :(得分:1)
我认为您的正则表达式不正确,请尝试(([A-Za-z0-9]*)[:,]?)*
编辑:纠正波特指出的错误:(([A-Za-z0-9]*)[:,]?)*([A-Za-z0-9]+)
最后 - 最佳版本:(([A-Za-z]+[0-9]+)[:,]?)*([A-Za-z]+[0-9]+)
//啊好吧这可能不会工作......但回答 1。 - 不,我不认为你的正则表达式是正确的
()组成一个小组
[] 形成一个charclass(你可以使用A-Z a-d 0-9等或只是单个字符)
?表示1或0
*
表示0或任何
id建议阅读http://www.regular-expressions.info/reference.html。
那是我前一段时间学习正则表达式的原因;)
对于构建表达式,我使用 Rad Software Regular Expression Designer
答案 4 :(得分:1)
让我们一步一步地构建它。
如果您遵循Excel寻址格式,要匹配CSL中的单个单元格条目,您将使用正则表达式:
[A-Z]{1,2}[1-9]\d*
按顺序匹配以下内容:
Any character in A to Z once or twice Any digit in 1 to 9 Any digit zero or more times
数字表达式将阻止输入带前导零的单元格地址。
要构建允许单元格地址对的表达式,请将冒号前面的表达式重复为可选。
[A-Z]{1,2}[1-9]\d*(:[A-Z]{1,2}[1-9]\d*)?
现在允许重复前面带逗号零次或多次的模式,并添加开始和结束字符串分隔符。
^[A-Z]{1,2}[1-9]\d*(:[A-Z]{1,2}[1-9]\d*)?(,[A-Z]{1,2}[1-9]\d*(:[A-Z]{1,2}[1-9]\d*)?)*$
我承认,有点长而讨厌,但在尝试了足够多的变种之后,我找不到缩短它的方法。
希望这有用。