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
此图片可能有用:
我想知道这是设计还是我的正则表达式有问题?是否positive lookahead assertion
的尝试可能有用。
答案 0 :(得分:3)
无论您是否创建了捕获,.Replace()
始终替换整个匹配。来自MSDN:
<强> Regex.Replace Method (String, String) 强>
在指定的输入字符串中,替换匹配a的所有字符串 带有指定替换字符串的正则表达式模式。
这是设计的,并且是所有正则表达式中的预期行为。你是对的,你需要为扩展使用一个组,并在替换中反向引用它。
额外评论:不需要在(\(\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