替换忽略非捕获组

时间:2015-09-26 00:43:33

标签: regex vb.net

Regex.Replace为什么忽略我的非捕获组?我正在删除文件名末尾出现的括号内的数字,无论是后面是0,1或2个扩展名。例如,

  

任何(54).XML

将成为

  

whatever.xml

这不起作用:

Private Function FixFileName(ByVal fn As String) As String
    Static rgx As New Regex("(\(\d+\))(?:(\.\w{2,3}){0,2})$")
    Return rgx.Replace(fn, "", 1)
End Function

它会在数字后删除扩展名,即使我没有捕获它们。这有效:

Private Function FixFileName(ByVal fn As String) As String
    Static rgx As New Regex("(\(\d+\))((\.\w{2,3}){0,2})$")
    Return rgx.Replace(fn, "$2", 1)
End Function

通过捕获,然后重新插入扩展(如果有的话)。

一些测试代码:

Option Strict On
Option Explicit On

Imports System.Text.RegularExpressions

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        RichTextBox1.WordWrap = False
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
            Handles Button1.Click
        Dim filenames() As String = {"wibble(a).xml", "blah (blah( blah)).xml", "blah(54)",
                                     "blahblah(433).xml", "blah(2)blah(500)", "blah(23)blah(500).xml",
                                     "blah(23)blah(500).xml.doh"}

        For Each filename As String In filenames
            RichTextBox1.AppendText(filename & " --> " & FixFileName(filename) & vbNewLine)
        Next
    End Sub

此图片可能有用:

regex101

我想知道这是设计还是我的正则表达式有问题?是否positive lookahead assertion的尝试可能有用。

1 个答案:

答案 0 :(得分:3)

无论您是否创建了捕获,.Replace()始终替换整个匹配。来自MSDN

  

<强> Regex.Replace Method (String, String)
  在指定的输入字符串中,替换匹配a的所有字符串   带有指定替换字符串的正则表达式模式。

这是设计的,并且是所有正则表达式中的预期行为。你是对的,你需要为扩展使用一个组,并在替换中反向引用它。

额外评论:不需要在(\(\d+\))中使用群组,因为您不需要捕获它(或者至少不在您提供的示例中)。 \(\d+\)可以正常工作。

然后你再次对,你可以使用lookahead来断言而不会在比赛中消耗掉角色。

正则表达式:(剧透)

  

\(\d+\)(?=(?:\.\w{2,3}){0,2}$)

  • 将鼠标移到上面的块上以查看前瞻性的正则表达式(在问题中你是否想要解决方案或仅知道它是否可行) < / LI>

输出

wibble(a).xml --> wibble(a).xml
blah (blah( blah)).xml --> blah (blah( blah)).xml
blah(54) --> blah
blahblah(433).xml --> blahblah.xml
blah(2)blah(500) --> blah(2)blah
blah(23)blah(500).xml --> blah(23)blah.xml
blah(23)blah(500).xml.doh --> blah(23)blah.xml.doh

DEMO