我正在努力想出一个正则表达式模式,它可以帮助我确定字符串是单元格的地址还是单元格的名称。
以下是单元格地址的一些示例:
以下是单元名称的一些示例:
我已经能够想出几种方法来确定字符串不是什么:
感谢您的帮助!
答案 0 :(得分:4)
好的,这个很有趣:
^\$?[A-Z]+\$?\d+(?::\$?[A-Z]+\$?\d+)?(?:,\s*(?:\$?[A-Z]+\$?\d+(?::\$?[A-Z]+\$?\d+)?))*$
让它分解,因为它相当令人讨厌。真正的神奇子模式就是:
\$?[A-Z]+\$?\d+
这个小东西将匹配任何单个有效单元格地址,并带有可选的绝对值$
s。下一位,
(?::\$?[A-Z]+\$?\d+)?
会选择匹配相同的东西(最后是?
量词),但前面跟冒号(:
)。这让我们得到了范围。下一位,
(?:,\s*(?:\$?[A-Z]+\$?\d+(?::\$?[A-Z]+\$?\d+)?))*
匹配与第一个相同的东西,但是零次或多次(使用*
量词),并且前面有逗号和可选空格,使用特殊的\s
标记(这意味着&#34 ;任何空白")。
如果我们想要变得非常花哨(并且,请注意,我不知道Excel的正则表达式引擎是否支持这个;我只是为了好玩而写它),我们可以使用recursion来完成同样的事情:
^((\$?[A-Z]+\$?\d+)(?::(?2))?)(?:,\s*(?1))*$
在这种情况下,魔术\$?[A-Z]+\$?\d+
位于第二个捕获组内,由(?2)
令牌递归使用。单个地址或范围的整个子模式包含在第一个捕获组中,然后用于匹配列表中的其他地址或范围。
答案 1 :(得分:1)
所以这里是VBA的正则表达式,它将找到任何单元格引用,无论它在哪里。
注意:我假设您在Formula
对象上执行此操作,因此不需要位于字符串的开头或结尾;所以你可以有一个包含单元格引用和单元格名称的字符串,它只会获取单元格引用,如下所示:
(?:\W|^)(\$?[A-Z]{1,3}\$?[0-9]{1,7}(:\$?[A-Z]{1,3}\$?[0-9]{1,7})?)(?!\w)
(?:\W|^)
位于开头,确保在字符串或字符串开头之前有一个非单词字符(如果始终有|^
,则删除=
从Formula
个对象开始)--- VBA我发现遗憾的是没有正常的负面看法背后)
(\$?[A-Z]{1,3}\$?[0-9]{1,7}(:\$?[A-Z]{1,3}\$?[0-9]{1,7})?)
找到实际的单元格引用,并在下面细分:
\$?[A-Z]{1,3}\$?[0-9]{1,7}
匹配一至三个大写字母(适用于Excel的可能当前范围; (:\$?[A-Z]{1,3}\$?[0-9]{1,7})?
与上述内容相同,只是在列?
使其成为可选项后,它会添加第二个单元格引用的选项。 (?!\w)
是一个消极的期待,并说它后面的字符不能是一个单词字符(可能在函数中,你可以在单元格引用周围唯一的东西是括号和运算符)。
我在Excel中编写了一个VBA函数,并使用上面的RegEx返回了以下内容:
注意:如果字符的顺序正确,则显然不会显示,因为尽管不可能,但仍会返回引用$AZO113:A4
。
答案 2 :(得分:0)
在尝试了几个解决方案后,我不得不修改一个正则表达式,所以它对我有用。我的版本只支持非命名范围。
((?![\=,\(\);])(\w+!)|('.+'!))?((\$?[A-Z]{1,3}\$?[0-9]{1,7}(:\$?[A-Z]{1,3}\$?[0-9]{1,7})?)|(\$?[A-Z]{1,3}(:\$?[A-Z]{1,3}\$?)))
它将在以下所有情况下捕获范围
=FUNCTION(F:F)
=FUNCTION($B22,G$5)
=SUM($F$10:$F$11)
=$J10-$K10
=SUMMARY!D4
我为RegEx创建了以下函数。但首先勾选参考" Microsoft VBScript正则表达式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