正则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返回了以下内容:

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