14

这可能是一个简单的问题,但不幸的是我无法得到我想要的结果......

说,我有以下行:

"Wouldn't It Be Nice" (B. Wilson/Asher/Love)

我将不得不寻找这种模式:

" (<any string>)

为了检索:

B. Wilson/Asher/Love

我尝试了类似的东西,"" (([^))]*))但它似乎不起作用。另外,我想使用Match.Submatches(0)这样可能会使事情变得有点复杂,因为它依赖于括号......

4

6 回答 6

25

编辑:检查您的文档后,问题是括号前有不间断的空格,而不是常规空格。所以这个正则表达式应该可以工作:""[ \xA0]*\(([^)]+)\)

""       'quote (twice to escape)
[ \xA0]* 'zero or more non-breaking (\xA0) or a regular spaces
\(       'left parenthesis
(        'open capturing group
[^)]+    'anything not a right parenthesis
)        'close capturing group
\)       'right parenthesis

在一个函数中:

Public Function GetStringInParens(search_str As String)
Dim regEx As New VBScript_RegExp_55.RegExp
Dim matches
    GetStringInParens = ""
    regEx.Pattern = """[ \xA0]*\(([^)]+)\)"
    regEx.Global = True
    If regEx.test(search_str) Then
        Set matches = regEx.Execute(search_str)
        GetStringInParens = matches(0).SubMatches(0)
    End If
End Function
于 2012-06-05T20:17:59.793 回答
4

严格来说,不是对您的问题的回答,但有时,对于某些事情,这个简单、好的 ol' 字符串函数比正则表达式更容易混淆和简洁。

Function BetweenParentheses(s As String) As String
    BetweenParentheses = Mid(s, InStr(s, "(") + 1, _
        InStr(s, ")") - InStr(s, "(") - 1)
End Function

用法:

Debug.Print BetweenParentheses("""Wouldn't It Be Nice"" (B. Wilson/Asher/Love)")
'B. Wilson/Asher/Love

编辑@alan 指出这将错误地匹配歌曲标题中括号的内容。稍加修改就可以轻松解决这个问题:

Function BetweenParentheses(s As String) As String
    Dim iEndQuote As Long
    Dim iLeftParenthesis As Long
    Dim iRightParenthesis As Long

    iEndQuote = InStrRev(s, """")
    iLeftParenthesis = InStr(iEndQuote, s, "(")
    iRightParenthesis = InStr(iEndQuote, s, ")")

    If iLeftParenthesis <> 0 And iRightParenthesis <> 0 Then
        BetweenParentheses = Mid(s, iLeftParenthesis + 1, _
            iRightParenthesis - iLeftParenthesis - 1)
    End If
End Function

用法:

Debug.Print BetweenParentheses("""Wouldn't It Be Nice"" (B. Wilson/Asher/Love)")
'B. Wilson/Asher/Love
Debug.Print BetweenParentheses("""Don't talk (yell)""")
' returns empty string

当然,这比以前不那么简洁了!

于 2012-06-06T07:17:22.617 回答
3

这是一个不错的正则表达式

".*\(([^)]*)

在 VBA/VBScript 中:

Dim myRegExp, ResultString, myMatches, myMatch As Match
Dim myRegExp As RegExp
Set myRegExp = New RegExp
myRegExp.Pattern = """.*\(([^)]*)"
Set myMatches = myRegExp.Execute(SubjectString)
If myMatches.Count >= 1 Then
    Set myMatch = myMatches(0)
    If myMatch.SubMatches.Count >= 3 Then
        ResultString = myMatch.SubMatches(3-1)
    Else
        ResultString = ""
    End If
Else
    ResultString = ""
End If

这匹配

Put Your Head on My Shoulder

"Don't Talk (Put Your Head on My Shoulder)"  

更新 1

我让正则表达式在您的 doc 文件上松散,它按要求匹配。很确定正则表达式没问题。我对 VBA/VBScript 不流利,但我猜这就是它出错的地方

如果您想进一步讨论正则表达式,我可以。我并不急于开始深入研究这个看起来很神秘的 VBscript API。

给定新的输入,正则表达式被调整为

".*".*\(([^)]*)

这样它就不会错误地匹配出现在引号内的 (Put Your Head on My Shoulder)。

在此处输入图像描述

于 2012-06-05T19:13:02.747 回答
2

此函数适用于您的示例字符串:

Function GetArtist(songMeta As String) As String
  Dim artist As String
  ' split string by ")" and take last portion
  artist = Split(songMeta, "(")(UBound(Split(songMeta, "(")))
  ' remove closing parenthesis
  artist = Replace(artist, ")", "")
End Function

前任:

Sub Test()

  Dim songMeta As String

  songMeta = """Wouldn't It Be Nice"" (B. Wilson/Asher/Love)"

  Debug.Print GetArtist(songMeta)

End Sub

将“B. Wilson/Asher/Love”打印到即时窗口。

它也解决了艾伦提到的问题。前任:

Sub Test()

  Dim songMeta As String

  songMeta = """Wouldn't (It Be) Nice"" (B. Wilson/Asher/Love)"

  Debug.Print GetArtist(songMeta)

End Sub

还将“B. Wilson/Asher/Love”打印到即时窗口。当然,除非艺术家姓名还包括括号。

于 2012-06-06T13:12:37.250 回答
1

这是另一个用 vbscript (?:\()(.*)(?:\)) Demo 测试的正则表达式 Here


Data = """Wouldn't It Be Nice"" (B. Wilson/Asher/Love)"
wscript.echo Extract(Data)
'---------------------------------------------------------------
Function Extract(Data)
Dim strPattern,oRegExp,Matches
strPattern = "(?:\()(.*)(?:\))"
Set oRegExp = New RegExp
oRegExp.IgnoreCase = True 
oRegExp.Pattern = strPattern
set Matches = oRegExp.Execute(Data) 
If Matches.Count > 0 Then Extract = Matches(0).SubMatches(0)
End Function
'---------------------------------------------------------------
于 2020-10-18T09:39:49.873 回答
0

我认为您需要一个更好的数据文件;)您可能需要考虑将文件预处理为临时文件以进行修改,以便将不符合您的模式的异常值修改为符合您的模式的位置。这样做有点费时,但是当数据文件缺乏一致性时总是很困难。

于 2014-04-09T10:32:20.187 回答