C'est probablement un problème simple, mais malheureusement, je n'ai pas pu obtenir les résultats souhaités ...
Dis, j'ai la ligne suivante:
"Wouldn't It Be Nice" (B. Wilson/Asher/Love)
Je devrais chercher ce modèle:
" (<any string>)
Pour récupérer:
B. Wilson/Asher/Love
J'ai essayé quelque chose comme "" (([^))]*))
mais cela ne semble pas fonctionner. Aussi, j'aimerais utiliser Match.Submatches(0)
afin que cela puisse compliquer un peu les choses car il repose sur des crochets ...
Éditer : Après avoir examiné votre document, le problème est qu'il y a des espaces insécables avant les parenthèses, pas des espaces normaux. Donc, cette expression rationnelle devrait fonctionner: ""[ \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
Dans une fonction:
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
Pas strictement une réponse à votre question, mais parfois, pour des choses aussi simples que cela, les bonnes vieilles fonctions de chaîne sont moins déroutantes et plus concises que Regex.
Function BetweenParentheses(s As String) As String
BetweenParentheses = Mid(s, InStr(s, "(") + 1, _
InStr(s, ")") - InStr(s, "(") - 1)
End Function
Usage:
Debug.Print BetweenParentheses("""Wouldn't It Be Nice"" (B. Wilson/Asher/Love)")
'B. Wilson/Asher/Love
EDIT@alan indique que cela va correspondre faussement au contenu des parenthèses dans le titre de la chanson. Ceci est facilement contourné avec une petite modification:
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
Usage:
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
Bien sûr, c'est moins concis qu'avant!
C'est un regex agréable
".*\(([^)]*)
Dans 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
Cela correspond
Put Your Head on My Shoulder
dans
"Don't Talk (Put Your Head on My Shoulder)"
Mise à jour 1
Je laisse la regex en vrac sur votre fichier doc et il correspond à la demande. Bien sûr, la regex va bien. Je ne parle pas couramment VBA/VBA, mais je suppose que c'est là que ça tourne mal
Si vous voulez discuter de la regex un peu plus, ça me convient. Je ne suis pas impatient de commencer à creuser dans cette API VBscript qui a l'air mystérieuse.
Compte tenu de la nouvelle entrée, la regex est peaufinée
".*".*\(([^)]*)
Pour qu'il ne corresponde pas faussement (Mettez votre tête sur mon épaule) qui apparaît à l'intérieur des guillemets.
Cette fonction a fonctionné sur votre exemple de chaîne:
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
Ex:
Sub Test()
Dim songMeta As String
songMeta = """Wouldn't It Be Nice"" (B. Wilson/Asher/Love)"
Debug.Print GetArtist(songMeta)
End Sub
imprime "B. Wilson/Asher/Love" dans la fenêtre immédiate.
Il résout également le problème alan mentionné . Ex:
Sub Test()
Dim songMeta As String
songMeta = """Wouldn't (It Be) Nice"" (B. Wilson/Asher/Love)"
Debug.Print GetArtist(songMeta)
End Sub
imprime également "B. Wilson/Asher/Love" dans la fenêtre immédiate. À moins bien sûr que les noms d’artistes incluent également des parenthèses.
Je pense que vous avez besoin d’un meilleur fichier de données;) Vous pouvez envisager de pré-traiter le fichier dans un fichier temporaire afin de le modifier, afin que les valeurs aberrantes qui ne correspondent pas à votre modèle soient modifiées en fonction de leur correspondance avec le modèle. Cela prend un peu de temps à faire, mais c'est toujours difficile lorsqu'un fichier de données manque de cohérence.