2015-09-26 76 views
1

为什么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可能会起作用。

+0

您是否在考虑之内'()',(如更换两个组数字。 'blah(23)blah(500).xml.doh'会导致'blahblah.xml.doh'?' –

+0

对不起,延迟回复,只是最后一组设置之前的任何扩展名。 –

回答

2

无论您是否创建捕获或不,.Replace()将始终取代整个匹配。从MSDN

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


这是由设计,并在所有的regex口味的预期行为。你是对的,你需要使用扩展的组,并在替换中反向引用它。

一个额外的评论:因为你不需要捕获它(或者至少不在你提供的例子中),所以不需要在(\(\d+\))中使用一个组。 \(\d+\)将工作得很好。

然后你又是对的,你可以使用lookahead来断言而不消耗比赛中的字符。

正则表达式:(扰流板)

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

  • 将鼠标移到上述嵌段看到正则表达式与先行(它在问题中不清楚您是想要解决方案还是只知道它是否可行)

输出:

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

+0

谢谢。我怀疑这是设计,只是无法找到一个明确的声明,表示非捕获将被忽略。 –

+0

事实上,这是因为未捕获不被忽略,以及捕获不被考虑。即使您使用捕获组,无捕获组或无,也会取代整个匹配。 – Mariano

+1

谢谢。 (捕获被认为在替换术语中使用“2美元”的程度)。 –