【问题标题】:Regular expression is treating group as a string正则表达式将组视为字符串
【发布时间】:2019-07-19 18:35:39
【问题描述】:

我有一个正则表达式,它使用来自另一个正则表达式的匹配值。但是当我测试正则表达式时,它没有捕获第二个正则表达式组。相反,它将组视为字符串。我如何让这个正则表达式输出组?

Private Sub CreateGraphicsFunction(sender As Object, e As EventArgs)
    Dim Regex = New Regex("infoEntityIdent=""(ICN.+?)[""].*?[>]")

    Dim ICNFiles = Directory.EnumerateFiles(MoveToPath, "*.*", SearchOption.AllDirectories)

    For Each tFile In ICNFiles
        Dim input = File.ReadAllText(tFile)

        Dim match = Regex.Match(input)
        If match.Success Then
            GraphicList.Add(match.Groups(1).Value)
            Dim Regex2 = New Regex("<!ENTITY " & match.Groups(1).Value & "  SYSTEM ""(ICN.+?[.]\w.+?)[""]")
            Debug.Write(Regex2)    ' outputs !ENTITY ICN-GAASIB0-00-051105-A-0YJB5-00005-A-001-01  SYSTEM "(ICN.+?[.]\w.+)["]
            Dim sysFileMatch = Regex2.Match(input)

            If sysFileMatch.Success Then
                ICNList.Add(sysFileMatch.Groups(1).Value)
                Debug.Write("found ICN " & sysFileMatch.Groups(1).Value)
            End If
        End If
    Next
End Sub

示例 第一个 Regex 捕获 ICN 编号。例如 使用此正则表达式可捕获 ICN 编号。

New Regex("infoEntityIdent=""(ICN.+?)[""].*?[>]")

从那里我想使用组中捕获的值再次浏览文件并找到匹配的 ICN 与 ext。例如 所以我使用新正则表达式中第一个正则表达式中捕获的组来获取带有扩展名的 ICN 号码。

New Regex("<!ENTITY " & match.Groups(1).Value & "  SYSTEM ""(ICN.+?[.]\w.+?)[""]")

当我测试这个正则表达式时,它给了我

!ENTITY ICN-GAASIB0-00-051105-A-0YJB5-00005-A-001-01  SYSTEM "(ICN.+?[.]\w.+)["]

它忽略了第二个正则表达式分组,而是将其视为字符串的一部分,而不是被用作一个组。我想要的是 SYSTEM 后带有扩展名的 ICN 号码

尝试使其工作的最新代码示例

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    Dim Files = Directory.EnumerateFiles(MovePath, "*.*", SearchOption.AllDirectories)

    For Each tFile In Files
        Dim input = File.ReadAllText(tFile)
        Dim strREGEX = New Regex("(?=[\S\s]*?infoEntityIdent\s*=\s*""\s*(ICN[\S\s]+?)\s*""[\S\s]*?>)[\S\s]*?<!ENTITY\s+\1\s+SYSTEM\s+""\s*(ICN[\S\s]+?\.\w[\S\s]+?)\s*")
        Dim match = strREGEX.Match(tFile)
        If match.Success Then
            Debug.Write(match.Groups(2).Value)
        Else
            Debug.Write(match.Groups(2).Value & " was not found")
        End If
    Next
End Sub

【问题讨论】:

  • &lt; 之前的!ENTITY[ ]ICN-GAASIB0-00-051105-A-0YJB5-00005-A-001-01[ ][ ]SYSTEM[ ]"(ICN.+?[.]\w.+)["] 发生了什么?
  • 问题 #2:你为什么使用 2 个正则表达式来匹配同一个字符串??
  • 只是一个参考和一些背景,如果你试图匹配一个 entity,即:&lt;!ENTITY[\S\s]*?&gt;,闭包要求你不能使用像这样的贪婪构造@ 987654329@ anywhere 在您的正则表达式中,同时尝试匹配实体标记中的某些内容。这是根据 w3c 规则...
  • 我正在搜索两个 REGEX 值,因为它们出现在文件的不同位置。我不能相信第一个发现有实体声明,所以我必须首先遍历这些 ICN 编号的文件。然后使用这些号码检查该 ICN 号码是否有匹配的实体。
  • 如果您只是在寻找包含任何 ICN 编号的 &lt;!ENTITY,您只需搜索即可。如果您希望将 infoEntityIdent= 值与它配对以在 ENTITY 中获得其他值,那么您应该按照我的回答进行操作。它更快且不易出错(作为一种方法)。

标签: regex vb.net


【解决方案1】:

将两个正则表达式组合成一个正则表达式。
这避免了人为干预错误的麻烦。

这是您实际的正则表达式组合成一个正则表达式。
我已经对其进行了调整,现在它是一个很好的正则表达式。
如果它不匹配,我没有办法检查它,你从来没有
发布了一个目标字符串。

原始:(?=[\S\s]*?infoEntityIdent\s*=\s*"\s*(ICN[\S\s]+?)\s*"[\S\s]*?&gt;)[\S\s]*?&lt;!ENTITY\s+\1\s+SYSTEM\s+"\s*(ICN[\S\s]+?\.\w[\S\s]+?)\s*"

字符串:@"(?=[\S\s]*?infoEntityIdent\s*=\s*""\s*(ICN[\S\s]+?)\s*""[\S\s]*?&gt;)[\S\s]*?&lt;!ENTITY\s+\1\s+SYSTEM\s+""\s*(ICN[\S\s]+?\.\w[\S\s]+?)\s*"""

格式化和解释:

 (?=                           # Look ahead to find the ID ICN
      [\S\s]*? 
      infoEntityIdent \s* = \s* 
      "
      \s* 
      ( ICN [\S\s]+? )              # (1), Entity IDent ICN
      \s* 
      " 
      [\S\s]*? >
 )
                               # Consume now:
 [\S\s]*?                      # Find the ID ICN inside an ENTITY
 <!ENTITY \s+ 
 \1                            # Back reference to Entity IDent ICN
 \s+ SYSTEM \s+ 
 "
 \s* 
 (                             # (2 start), Some other ICN junk
      ICN
      [\S\s]+? 
      \. 
      \w 
      [\S\s]+? 
 )                             # (2 end)
 \s* 
 "

【讨论】:

  • 我已将您的代码添加到我的帖子中。我仍然无法让它工作。你能看看并告诉我我做错了什么吗?@sln
  • 我将首先将这个Dim match = strREGEX.Match(tFile) 更改为这个Dim match = strREGEX.Match(input),这样您就不会尝试匹配文件句柄。此外,如果您没有发布像 input 这样可以测试正则表达式的字符串示例,请不要再问我任何问题。
【解决方案2】:

您很可能希望从第一次搜索中“转义”您的“未知”结果,以便能够在新的正则表达式中使用它。

类似:

Dim EscapedSearchValue As String = Regex.Escape(match.Groups(1).Value)
Dim Regex2 = New Regex("<!ENTITY " & EscapedSearchValue & "  SYSTEM ""(ICN.+?[.]\w.+?)[""]")

Regex.Escape(String) Method

【讨论】:

  • 我尝试添加 EscapedSearchValue,但它仍然将 Regex2 作为字符串接收
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-03
  • 1970-01-01
  • 2014-07-23
  • 1970-01-01
  • 1970-01-01
  • 2020-12-27
  • 1970-01-01
相关资源
最近更新 更多