正则expression式来确定一个string是一个范围的名称还是一个单元格的地址
我努力想出一个正则expression式模式,可以帮助我确定一个string是一个单元格的地址,还是一个单元格的名称。
以下是一些单元格地址的示例:
- “E5”
- “AA55:E5”
- “DD5555:DDD55555,E5,F5:AA55”
- “$ F7:$ G $ 7”
以下是单元名称的一些示例:
- “bis_document_id”
- “PCR1MM_YPCVolume”
- “sheet_error7”
- “blahE5”
- “training_A1”
- “myNameIsGeorgeJR”
有没有一个正则expression式模式,你们可以拿出来,将匹配所有的任何一组,而不是其他?
我已经能够想出几种方法来确定一个string不是什么:
- 如果它有任何其他字符而不是“$”或“:”,我知道这不是一个单元格的名称,最有可能是一个单元格的地址。
- 如果它有三个以上的连续号码,那很可能不是一个小区的地址。
- 一个单元格的地址在一个数字之前不可能有两个以上的字母,99.9%的单元格地址将在A到ZZ列中。
唉,这三个小testing很难certificate这个string是什么。
谢谢您的帮助!
好的,这个很好玩:
^\$?[AZ]+\$?\d+(?::\$?[AZ]+\$?\d+)?(?:,\s*(?:\$?[AZ]+\$?\d+(?::\$?[AZ]+\$?\d+)?))*$
让我们把它分解下来,因为它很讨厌。 神奇的子模式,实际上是这样的:
\$?[AZ]+\$?\d+
这个小东西将匹配任何单个有效的单元格地址,可选的绝对值$
s。 接下来的一点,
(?::\$?[AZ]+\$?\d+)?
将可选地匹配相同的东西(最后的?
量词),但以冒号(:)开头。 这让我们得到范围。 接下来的一点,
(?:,\s*(?:\$?[AZ]+\$?\d+(?::\$?[AZ]+\$?\d+)?))*
匹配与第一个相同的事物,但是零次或多次(使用*
量词),并且使用特殊的\s
标记(意思是“任何空格”)以逗号和可选空格开头。
演示Regex101
如果我们想要得到真正的幻想(并且介意你,我不知道Excel的正则expression式引擎是否支持这个;我只是为了好玩而写的),我们可以使用recursion来完成同样的事情:
^((\$?[AZ]+\$?\d+)(?::(?2))?)(?:,\s*(?1))*$
在这种情况下,魔术\$?[AZ]+\$?\d+
在第二个捕获组中,由(?2)
标记recursion地使用。 单个地址或其范围的整个子模式包含在第一个捕获组中,然后用于匹配列表中的其他地址或范围。
演示Regex101
所以这里是一个VBA的正则expression式,可以find任何单元格引用,而不pipe它在哪里。
注意:我假定你正在执行一个Formula
对象,因此不需要在string的开始或结束; 所以你可以有一个string的单元格引用和单元格名称,它只会选取单元格引用如下:
(?:\W|^)(\$?[AZ]{1,3}\$?[0-9]{1,7}(:\$?[AZ]{1,3}\$?[0-9]{1,7})?)(?!\w)
(?:\W|^)
是在开始,并确保在它之前或string的开始有一个非单词字符(如果它在开始时总是有一个=
如Formula
对象一样,删除|^
) – VBA我发现遗憾的是没有一个function负面lookbehind)
(\$?[AZ]{1,3}\$?[0-9]{1,7}(:\$?[AZ]{1,3}\$?[0-9]{1,7})?)
find实际的单元格引用,并在下面分解:
-
\$?[AZ]{1,3}\$?[0-9]{1,7}
匹配一到三个大写字母(适用于Excel可能的电stream范围; -
(:\$?[AZ]{1,3}\$?[0-9]{1,7})?
除了在列之后添加第二个单元格引用的选项之外,它和上面的一样?
使其成为可选。
(?!\w)
是一个负面的期待,并说它后面的字符不能是一个单词字符(大概在函数中,你可以在单元格引用的唯一东西是括号和运算符)。
我在Excel中编写了一个VBA函数,它用上面的RegEx返回了以下内容:
注意:如果字符按照正确的顺序显示不会很明显,因为参考$AZO113:A4
被返回,尽pipe这是不可能的。
尝试了几个解决scheme后,我不得不修改一个正则expression式,所以它适用于我。 我的版本只支持非命名的范围。
((?![\=,\(\);])(\w+!)|('.+'!))?((\$?[AZ]{1,3}\$?[0-9]{1,7}(:\$?[AZ]{1,3}\$?[0-9]{1,7})?)|(\$?[AZ]{1,3}(:\$?[AZ]{1,3}\$?)))
它将捕获以下所有情况下的范围
=FUNCTION(F:F) =FUNCTION($B22,G$5) =SUM($F$10:$F$11) =$J10-$K10 =SUMMARY!D4
我为RegEx创build了以下函数。 但首先从“工具”>“引用”中勾选“Microsoft VBScript Regular Expressions 5.5”的引用
Function RegExp(ByVal sText As String, ByVal sPattern, Optional bGlobal As Boolean = True, Optional bIgnoreCase As Boolean = False, Optional bArray As Boolean = False) As Variant Dim objRegex As New RegExp Dim Matches As MatchCollection Dim Match As Match Dim i As Integer objRegex.IgnoreCase = bIgnoreCase objRegex.Global = bGlobal objRegex.Pattern = sPattern If objRegex.test(sText) Then Set Matches = objRegex.Execute(sText) If Matches.count <> 0 Then If bArray Then ' if we want to return array instead of MatchCollection ReDim aMatches(Matches.count - 1) As Variant For Each Match In Matches aMatches(i) = Match.value i = i + 1 Next RegExp = aMatches Else Set RegExp = Matches End If End If End If End Function