Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 用于确定字符串是范围名称还是单元格名称的正则表达式';地址_Regex_Excel_Vba - Fatal编程技术网

Regex 用于确定字符串是范围名称还是单元格名称的正则表达式';地址

Regex 用于确定字符串是范围名称还是单元格名称的正则表达式';地址,regex,excel,vba,Regex,Excel,Vba,我正在努力找到一种正则表达式模式,它可以帮助我确定字符串是单元格地址还是单元格名称 以下是一些单元格地址的示例: “E5” “AA55:E5” “DD5555:DDD55555、E5、F5:AA55” “$F7:$G$7” 以下是一些单元格名称的示例: “bis_文件_id” “PCR1MM_YPCVolume” “第7页” “布拉赫5” “培训A1” “我的名字是乔治” 你们能想出一个正则表达式模式来匹配任何一个组而不是其他组吗? 我已经能够想出几种方法来确定字符串不是什么: 如果其

我正在努力找到一种正则表达式模式,它可以帮助我确定字符串是单元格地址还是单元格名称

以下是一些单元格地址的示例:

  • “E5”
  • “AA55:E5”
  • “DD5555:DDD55555、E5、F5:AA55”
  • “$F7:$G$7”
以下是一些单元格名称的示例:

  • “bis_文件_id”
  • “PCR1MM_YPCVolume”
  • “第7页”
  • “布拉赫5”
  • “培训A1”
  • “我的名字是乔治”
你们能想出一个正则表达式模式来匹配任何一个组而不是其他组吗? 我已经能够想出几种方法来确定字符串不是什么:

  • 如果其中有“$”或“:”以外的其他字符,我知道它不是单元格的名称,很可能是单元格的地址
  • 如果它有三个以上的连续数字,它很可能不是一个单元格的地址
  • 一个单元格的地址不太可能在一个数字前有超过2个字母,99.9%的单元格地址将在A列到ZZ列中
唉,这三个小测试很难证明这个字符串是什么

谢谢你的帮助

好的,这个很有趣:

^\$?[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+)?))*
将可选地匹配相同的内容(末尾的
量词),但前面有冒号(
)。这让我们得到了射程。下一位,

(?::\$?[A-Z]+\$?\d+)?
(?:,\s*(?:\$?[A-Z]+\$?\d+(?::\$?[A-Z]+\$?\d+)?))*
匹配与第一个相同的内容,但匹配次数为零或更多(使用
*
量词),前面是逗号,前面是使用特殊
\s
标记(表示“任何空白”)的可选空格

如果我们真的想变得有趣(请注意,我不知道Excel的regex引擎是否支持这一点;我只是为了好玩才写的),我们可以用它来完成同样的事情:

^((\$?[A-Z]+\$?\d+)(?::(?2))?)(?:,\s*(?1))*$
在这种情况下,magic
\$?[A-Z]+\$?\d+
位于第二个捕获组内,由
(?2)
令牌递归使用。单个地址或其范围的整个子模式包含在第一个捕获组中,然后用于匹配列表中的其他地址或范围


这里有一个VBA的正则表达式,它可以找到任何单元格引用,不管它在哪里

注意:我假设您在
公式
对象上执行此操作,因此不需要位于字符串的开头或结尾;因此,您可以有一个包含单元格引用和单元格名称的字符串,它将只拾取单元格引用,如下所示:

(?:\W|^)(\$?[A-Z]{1,3}\$?[0-9]{1,7}(:\$?[A-Z]{1,3}\$?[0-9]{1,7})?)(?!\w)
(?:\W | ^)
位于开头,并确保在它之前或字符串的开头有一个非单词字符(删除
| ^
,如果它在开头总是有一个
=
,就像在
公式
对象中一样)--很遗憾,我发现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函数,它使用上述正则表达式返回以下内容:


注意:如果字符的顺序正确,它显然不起作用,因为引用
$AZO113:A4
被返回,尽管这是不可能的。

在尝试了几种解决方案后,我不得不修改一个正则表达式,使其适用于我。我的版本只支持未命名的范围

((?![\=,\(\);])(\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
我为正则表达式创建了以下函数。但首先,请在“工具”>“引用”中勾选对“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
函数RegExp(ByVal sText作为字符串,ByVal sPattern,可选bGlobal作为Boolean=True,可选bIgnoreCase作为Boolean=False,可选bArray作为Boolean=False)作为变量
Dim objRegex作为新的RegExp
将匹配项设置为MatchCollection
暗配
作为整数的Dim i
objRegex.IgnoreCase=bIgnoreCase
objRegex.Global=bGlobal
objRegex.Pattern=飞溅
如果是objRegex.test(sText),则
Set Matches=objRegex.Execute(sText)
如果匹配,则计数为0
如果bArray那么“如果我们想返回数组而不是MatchCollection
作为变体重拨aMatches(Matches.count-1)
比赛中的每一场比赛
A匹配(i)=匹配值
i=i+1
下一个
RegExp=aMatches
其他的
Set RegExp=匹配项
如果结束
如果结束
如果结束
端函数

可能更简单:您需要正则表达式模式吗?只是随便玩玩,我认为您可以编写一个简单的脚本,检查单元格是否为有效范围。将单元格放入
范围(cel.value)。选择
,如果出现错误,则它不是一个范围…?也命名范围是此工作簿集合的一部分。名称@BruceWayne-
范围(“AA55:E5”)。选择
范围(“PCR1MM_YPCVolume”)。选择
都是有效语句(假设“PCR1MM_YPCVolume”是单元格/范围名称)所以不能用来区分范围地址和范围名称。这是一个实际的应用程序,还是你自己的lea