Regex 用正则表达式解析Excel引用?

Regex 用正则表达式解析Excel引用?,regex,vb.net,excel,Regex,Vb.net,Excel,Excel返回表单的引用 =Sheet1!R14C1R22C71junk (“垃圾”通常不会出现,但我想确保没有多余的文本。) 我想将其“拆分”为一个VB数组,其中 a(0)="Sheet1" a(1)="14" a(2)="1" a(3)="22" a(4)="71" a(5)="junk" 我相信用正则表达式可以很容易地完成,但我就是搞不懂它的诀窍。 有没有一个善良的灵魂可以帮助我 谢谢 应该有用 [^!]+匹配一系列非感叹号字符 \d+匹配一个数字序列 *匹配任何内容 因此,在VB.N

Excel返回表单的引用

=Sheet1!R14C1R22C71junk
(“垃圾”通常不会出现,但我想确保没有多余的文本。)

我想将其“拆分”为一个VB数组,其中

a(0)="Sheet1"
a(1)="14"
a(2)="1"
a(3)="22"
a(4)="71"
a(5)="junk"
我相信用正则表达式可以很容易地完成,但我就是搞不懂它的诀窍。 有没有一个善良的灵魂可以帮助我

谢谢

应该有用

[^!]+
匹配一系列非感叹号字符

\d+
匹配一个数字序列

*
匹配任何内容

因此,在VB.NET中:

Dim a As Match
a = Regex.Match(SubjectString, "=([^!]+)!R(\d+)C(\d+)R(\d+)C(\d+)(.*)")
If a.Success Then
    ' matched text: a.Value
    ' backreference n text: a.Groups(n).Value
Else
    ' Match attempt failed
End If
应该有用

[^!]+
匹配一系列非感叹号字符

\d+
匹配一个数字序列

*
匹配任何内容

因此,在VB.NET中:

Dim a As Match
a = Regex.Match(SubjectString, "=([^!]+)!R(\d+)C(\d+)R(\d+)C(\d+)(.*)")
If a.Success Then
    ' matched text: a.Value
    ' backreference n text: a.Groups(n).Value
Else
    ' Match attempt failed
End If

一个简单的
字符串。如果没有“垃圾”文本,拆分就可以了:

Dim input As String = "=Sheet1!R14C1R22C71"
Dim result = input.Split(New Char() { "="c, "!"c, "R"c, "C"c }, StringSplitOptions.RemoveEmptyEntries)
For Each item As String In result
    Console.WriteLine(item)
Next
正则表达式变得有点棘手,因为您需要遍历嵌套部分的组和捕获以获得正确的顺序

编辑:这是我的正则表达式解决方案。它接受R和C的多次出现

Dim input As String = "=Sheet1!R14C1R22C71junk"
Dim pattern As String = "=(?<Sheet>Sheet\d+)!(?:R(?<R>\d+)C(?<C>\d+))+"

Dim m As Match = Regex.Match(input, pattern)
If m.Success Then
    Console.WriteLine(m.Groups("Sheet").Value)
    For i = 0 To m.Groups("R").Captures.Count - 1
        Console.WriteLine(m.Groups("R").Captures(i).Value)
        Console.WriteLine(m.Groups("C").Captures(i).Value)
    Next
End If
Dim输入为字符串=“=Sheet1!r14c1r22c71crunk”
尺寸模式为String=“=(?图纸\d+)(?:R(?\d+)C(?\d+)”
Dim m As Match=Regex.Match(输入,模式)
如果m.成功了那么
控制台写入线(m.组(“表”).值)
对于i=0到m.Groups(“R”).Captures.Count-1
Console.WriteLine(m.Groups(“R”).捕获(i.Value)
Console.WriteLine(m.Groups(“C”).捕获(i.Value)
下一个
如果结束
模式说明:

  • “=(?工作表\d+):匹配后跟“工作表”和数字的=符号。使用“工作表”的命名组
  • “!(?:R(?\d+)C(?\d+)+”:匹配感叹号,后跟文本中至少一个出现的*R*xx*C*xx部分。使用“R”和“C”的命名组
  • “(?:…)+”:上述部分中的此部分匹配,但不捕获内部模式(即R/C部分)。这是为了避免在实际使用命名组捕获它们时不必要地捕获它们

    • 一个简单的
      字符串。如果没有“垃圾”文本,拆分
      就可以了:

      Dim input As String = "=Sheet1!R14C1R22C71"
      Dim result = input.Split(New Char() { "="c, "!"c, "R"c, "C"c }, StringSplitOptions.RemoveEmptyEntries)
      For Each item As String In result
          Console.WriteLine(item)
      Next
      
      正则表达式变得有点棘手,因为您需要遍历嵌套部分的组和捕获以获得正确的顺序

      编辑:这是我的正则表达式解决方案。它接受R和C的多次出现

      Dim input As String = "=Sheet1!R14C1R22C71junk"
      Dim pattern As String = "=(?<Sheet>Sheet\d+)!(?:R(?<R>\d+)C(?<C>\d+))+"
      
      Dim m As Match = Regex.Match(input, pattern)
      If m.Success Then
          Console.WriteLine(m.Groups("Sheet").Value)
          For i = 0 To m.Groups("R").Captures.Count - 1
              Console.WriteLine(m.Groups("R").Captures(i).Value)
              Console.WriteLine(m.Groups("C").Captures(i).Value)
          Next
      End If
      
      Dim输入为字符串=“=Sheet1!r14c1r22c71crunk”
      尺寸模式为String=“=(?图纸\d+)(?:R(?\d+)C(?\d+)”
      Dim m As Match=Regex.Match(输入,模式)
      如果m.成功了那么
      控制台写入线(m.组(“表”).值)
      对于i=0到m.Groups(“R”).Captures.Count-1
      Console.WriteLine(m.Groups(“R”).捕获(i.Value)
      Console.WriteLine(m.Groups(“C”).捕获(i.Value)
      下一个
      如果结束
      
      模式说明:

      • “=(?工作表\d+):匹配后跟“工作表”和数字的=符号。使用“工作表”的命名组
      • “!(?:R(?\d+)C(?\d+)+”:匹配感叹号,后跟文本中至少一个出现的*R*xx*C*xx部分。使用“R”和“C”的命名组
      • “(?:…)+”:上述部分中的此部分匹配,但不捕获内部模式(即R/C部分)。这是为了避免在实际使用命名组捕获它们时不必要地捕获它们

      R1C1样式的更通用正则表达式:

      ^=(?:(?<Sheet>[^!]+)!)?(?:R((?<RAbs>\d+)|(?<RRel>\[-?\d+\]))C((?<CAbs>\d+)|(?<CRel>\[-?\d+\]))){1,2}$
      
      ^=(?:(?[^!]+)!(?:R((?\d+)|(?\[-?\d+))C((?\d+)|(?\[-?\d+))){1,2}$
      
      和A1样式:

      ^=(?:(?<Sheet>[^!]+)!)?(?:(?<Col1>\$?[a-z]+)(?<Row1>\$?\d+))(?:\:(?<Col2>\$?[a-z]+)(?<Row2>\$?\d+))?$
      
      ^=(?:(?[^!]+)!(?:(?\$?[a-z]+)(?\$?\d+)(?::(?\$?[a-z]+)(?\$?\d+)$
      

      它与外部引用不匹配,如=[Book1]Sheet1!A1尽管如此。

      R1C1样式更通用的正则表达式:

      ^=(?:(?<Sheet>[^!]+)!)?(?:R((?<RAbs>\d+)|(?<RRel>\[-?\d+\]))C((?<CAbs>\d+)|(?<CRel>\[-?\d+\]))){1,2}$
      
      ^=(?:(?[^!]+)!(?:R((?\d+)|(?\[-?\d+))C((?\d+)|(?\[-?\d+))){1,2}$
      
      和A1样式:

      ^=(?:(?<Sheet>[^!]+)!)?(?:(?<Col1>\$?[a-z]+)(?<Row1>\$?\d+))(?:\:(?<Col2>\$?[a-z]+)(?<Row2>\$?\d+))?$
      
      ^=(?:(?[^!]+)!(?:(?\$?[a-z]+)(?\$?\d+)(?::(?\$?[a-z]+)(?\$?\d+)$
      

      它与外部引用不匹配,如=[Book1]Sheet1!A1尽管如此。

      谢谢您的快速回复。嗯,这个正则表达式很复杂。但这也可以接受“=Sheet1!xx14yyyyyzz22w71”不是吗?我想确定是Rs和Cs。“垃圾”也可以是任意长度的垃圾,以非数字开头,而不仅仅是一个单词。可能吗?是的,应该行。点将匹配任何内容,并且前面的
      \d+
      已经用完了所有数字。我还修改了正则表达式,以适应第一个非数字(离题)的文字R和C.A(4)结尾。我是这里的初学者。你是如何尽快得到通知的?对不起,我在你回复时编辑了我的评论-我误读了你之前的评论。当您刷新页面或访问堆栈溢出的其他页面时,您会收到有关新注释的通知(小邮箱图标亮起,左上角的“Stack Exchange”符号显示新注释的数字。感谢您的快速回复。嗯,这是一个复杂的正则表达式。但也可以接受“=Sheet1!XX14YYYYZZ22W71”不是吗?我想确定它是Rs和Cs。而且“垃圾”可以是任意长度的垃圾,以非数字开头,而不仅仅是一个单词。可能吗?是的,这应该可以。点匹配任何东西,前面的
      \d+
      已经用完了所有数字。我还更改了正则表达式以适应文字R和C.a(4)在第一个非数字(主题外)处结束。我是这里的初学者。如何尽快得到通知?抱歉,我在您回答时编辑了我的评论-我误读了您以前的评论。当您刷新页面或访问堆栈溢出上的其他页面时,您会收到关于新评论的通知(小邮箱图标亮起,左上角的“Stack Exchange”符号显示一个带有新注释的数字。+1表示智能、简单的解决方案,即使它没有捕获垃圾。Thanks@smirkingman谢谢。我现在也添加了一个正则表达式解决方案,可以处理“