Here’s a script i use to test them in AppleScript.
At the end is a bunch of commented out “tests” or examples you might find useful
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
property NSRegularExpression : a reference to current application's NSRegularExpression
property NSRegularExpressionCaseInsensitive : a reference to 1
property NSRegularExpressionUseUnicodeWordBoundaries : a reference to 40
property NSRegularExpressionAnchorsMatchLines : a reference to 16
property NSRegularExpressionSearch : a reference to 1024
property NSString : a reference to current application's NSString
property myTestName : ""
property mySourceA : ""
property mySourceB : ""
property myPattern1 : ""
property myPattern2 : ""
property myReplace : ""
property myTestA1 : ""
property myTestA2 : ""
property myTestB1 : ""
property myTestB2 : ""
property myTestExpect1 : ""
property myTestExpect2 : ""
property logRegEx : true
property logResults : true
property logDebug : false
-- RUN TEMPLATE
-- \\b(WAV|24 bit|96|19\\.2)\\b
-- NEED FLAC MISSING BAD LOW REPLACE NOT LIVE
set aWordsPattern1 to my createPatternForMatchAnyWords:"WAV 24%bit 96 19.2"
set aWordsPattern2 to my createPatternForMatchAnyWords:"NEED%FLAC MISSING BAD LOW REPLACE NOT LIVE"
my testRegWithName:"TRACK QUALITY SCANNING TAGS FOR CONATINS" pattern1:aWordsPattern1 pattern2:aWordsPattern2 source1:"FLAC 24 bit - 19.2 kHz" source2:"missing" replaceWith:"MATCHED" expecting1:"" expecting2:""
-- MAIN SCRIPT OBJECT FUNCTIONS
on testRegWithName:aName pattern1:patternNo1 pattern2:patternNo2 ¬
source1:sourceA source2:sourceB replaceWith:aReplace ¬
expecting1:expectNo1 expecting2:expectNo2
my resetValues()
set myTestName to aName
if not patternNo1 is "" then set myPattern1 to patternNo1
if not patternNo2 is "" then set myPattern2 to patternNo2
if not sourceA is "" then set mySourceA to sourceA
if not sourceB is "" then set mySourceB to sourceB
if not aReplace is "" then set myReplace to aReplace
if not expectNo1 is "" then set myTestExpect1 to expectNo1
if not expectNo2 is "" then set myTestExpect2 to expectNo2
my runTestA()
my runTestB()
if logResults then my logTestResults()
end testRegWithName:pattern1:pattern2:source1:source2:replaceWith:expecting1:expecting2:
on resetValues()
set myTestName to ""
set myPattern1 to "NONE"
set myPattern2 to "NONE"
set mySourceA to "NONE"
set mySourceB to "NONE"
set myReplace to ""
set myTestA1 to "NONE"
set myTestA2 to "NONE"
set myTestB1 to "NONE"
set myTestB2 to "NONE"
set myTestExpect1 to "NONE"
set myTestExpect2 to "NONE"
end resetValues
on runTestA()
if mySourceA is "NONE" then
return
end if
if not myPattern1 is "NONE" then
set myTestA1 to my findInString:mySourceA withPattern:myPattern1 replaceWith:myReplace
end if
if not myPattern2 is "NONE" then
set myTestA2 to my findInString:mySourceA withPattern:myPattern2 replaceWith:myReplace
end if
end runTestA
on runTestB()
if mySourceB is "NONE" then
return
end if
if not myPattern1 is "NONE" then
set myTestB1 to my findInString:mySourceB withPattern:myPattern1 replaceWith:myReplace
end if
if not myPattern2 is "NONE" then
set myTestB2 to my findInString:mySourceB withPattern:myPattern2 replaceWith:myReplace
end if
end runTestB
on logTestResults()
log ("------------------------------------------- TEST RESULTS LOG")
log {"----------------myTestName is", myTestName}
log {"myPattern1 is", myPattern1}
log {"myPattern2 is", myPattern2}
log {"myReplace is", myReplace}
log {"--------------mySourceA is", mySourceA}
log {"myTestA1 is", myTestA1}
log {"myTestA2 is", myTestA2}
if not myTestExpect1 is "NONE" then
log {"myTestExpect1 is", myTestExpect1}
end if
log {"--------------mySourceB is", mySourceB}
log {"myTestB1 is", myTestB1}
log {"myTestB2 is", myTestB2}
if not myTestExpect2 is "NONE" then
log {"myTestExpect2 is", myTestExpect2}
end if
end logTestResults
-- MAIN FUNCTIONS
on findInString:aString withPattern:aRegExString replaceWith:aReplace
set aRegEx to my createRegularExpressionWithPattern:aRegExString
if logDebug then
log {"aRegEx is:", aRegEx}
end if
return (my findInString:aString withRegEx:aRegEx replaceWith:aReplace)
end findInString:withPattern:replaceWith:
on findInString:aString withRegEx:aRegEx replaceWith:aReplace
if logDebug then log ("findInString:withRegEx:replaceWith: START")
set aSource to NSString's stringWithString:aString
set aRepString to NSString's stringWithString:aReplace
set aLength to aSource's |length|()
set aRange to (current application's NSMakeRange(0, aLength))
set aCleanString to (aRegEx's stringByReplacingMatchesInString:aSource options:0 range:aRange withTemplate:aRepString)
return aCleanString
end findInString:withRegEx:replaceWith:
on createRegularExpressionWithPattern:aRegExString
if (class of aRegExString) is equal to (NSRegularExpression's class) then
log ("it alreadry was a RegEx")
return aRegExString
end if
set aPattern to NSString's stringWithString:aRegExString
set regOptions to NSRegularExpressionCaseInsensitive + NSRegularExpressionUseUnicodeWordBoundaries
set {aRegEx, aError} to (NSRegularExpression's regularExpressionWithPattern:aPattern options:regOptions |error|:(reference))
if (aError ≠ missing value) then
log {"regEx failed to create aError is:", aError}
log {"aError debugDescrip is:", aError's debugDescription()}
break
return
end if
return aRegEx
end createRegularExpressionWithPattern:
on createPatternForMatchAnyWords:aLine
set aString to NSString's stringWithString:aLine
set aArray to aString's componentsSeparatedByString:" "
set aPattern to NSString's stringWithString:"\\b("
if (logRegEx) then
log {"createPatternForMatchAnyWords aArray is:", aArray}
end if
set aTotal to (aArray's |count|())
repeat with i from 1 to aTotal
set aWord to aArray's item i
set aWord to (aWord's stringByReplacingOccurrencesOfString:"%" withString:" ")
set aWordPattern to (NSRegularExpression's escapedPatternForString:aWord)
if (i ≠ aTotal) then
set aWordPattern to (aWordPattern's stringByAppendingString:"|")
end if
if (logRegEx) then
log {"aWord is:", aWord}
log {"aWordPattern is:", aWordPattern}
end if
set aPattern to (aPattern's stringByAppendingString:aWordPattern)
end repeat
set aPattern to aPattern's stringByAppendingString:")\\b"
if (logRegEx) then
log {"final pattern is:", aPattern}
end if
return aPattern
end createPatternForMatchAnyWords:
on createPatternForMatchAllWords:aLine
set aString to NSString's stringWithString:aLine
set aArray to aString's componentsSeparatedByString:" "
set aPattern to NSString's stringWithString:"^"
if (logRegEx) then
log {"createPatternForMatchAllWords aArray is:", aArray}
end if
repeat with i from 1 to (aArray's |count|())
set aWord to aArray's item i
if ((aWord's |length|()) > 1) then
set aWordPattern to (my createPatternForMatchWord:aWord)
else
set aWordPattern to (my createPatternForMatchLetter:aWord)
end if
if (logRegEx) then
log {"aWordPattern is:", aWordPattern}
end if
set aPattern to (aPattern's stringByAppendingString:aWordPattern)
end repeat
set aPattern to aPattern's stringByAppendingString:".*$"
if (logRegEx) then
log {"final pattern is:", aPattern}
end if
return aPattern
end createPatternForMatchAllWords:
-- (?=.*\\bYou\\b)
on createPatternForMatchWord:aWord
set aWordPattern to NSString's stringWithString:"(?=.*\\b"
set aWordPattern to (aWordPattern's stringByAppendingString:aWord)
set aWordPattern to (aWordPattern's stringByAppendingString:".?\\b)")
return aWordPattern
end createPatternForMatchWord:
on createPatternForMatchLetter:aWord
set aWordPattern to NSString's stringWithString:"(?=.*\\b"
set aWordPattern to (aWordPattern's stringByAppendingString:aWord)
set aWordPattern to (aWordPattern's stringByAppendingString:".{0,2}\\b)")
return aWordPattern
end createPatternForMatchLetter:
(*
-- /(^.*?\\.){1}
my testRegWithName:"REMOVE FROM START TO FIRST PERIOD / ALT ALSO REMOVE TRACK." pattern1:"(^.*?\\.){1}" pattern2:"((?:^.*?\\.){1}(?:track\\.?)?)" source1:"@unionOfArrays.trackGenres" source2:"self.track.bitRate" replaceWith:"" expecting1:"" expecting2:""
*)
(*
-- ^(?=.*\\bYou\\b)(?=.*\\bKnow\\b)(?=.*\\bLove\\b)(?=.*\\bYou\\b).*$
--
set aWordsPattern1 to my createPatternForMatchAllWords:"You Know I Love You"
set aWordsPattern2 to my createPatternForMatchAllWords:"You Know I Fuck You"
my testRegWithName:"MATCH ALL WORDS IN LINE TITLE TEST 01" pattern1:aWordsPattern1 pattern2:aWordsPattern2 source1:"If You Love Me (Let Me Know)" source2:"I Didn't Know I Loved You" replaceWith:"MATCHED" expecting1:"" expecting2:""
*)
(*
my testRegWithName:"SINGLE ARTIST MATCH 3 MORE ADDS NO THE" pattern1:"(?>((^the\\s)|(\\s?(\\,|\\&|\\+)\\s?)|(\\s(and|vs)\\.?\\s)|^))(Eagles)(?>($|(\\,?\\s?)))" pattern2:"(?>((\\s?(\\,|\\&|\\+)\\s?)|(\\s(and|vs)\\.?\\s)|^))(Eagles)(?>($|(\\,?\\s?)))" source1:"The Eagles CCR, Eagles Rolling Stones The Eagles of Death and Eagles II" source2:"CCR, Eagles, Rolling Stones & eagles plus Eagles of Death vs Eagles" replaceWith:"$1MATCHED$8" expecting1:"" expecting2:""
-- ((^.*)(?:(^the\s)|(\,\s?)|^)((Red)*.*(Hot)*.*(Chili)*.*(Peppers)*)(?:$|\,)(.*+))
*)
(*
my testRegWithName:"SINGLE ARTIST MATCH" pattern1:"(?:(^the\\s)|(\\,\\s?)|^)(Eagles)(?:$|\\,)" pattern2:"((^.*)(?:(^the\\s)|(\\,\\s?)|^)(Eagles)(?:$|\\,)(.*+))" source1:"The Eagles of DeathMetal" source2:"CCR, Eagles, Rolling Stones" replaceWith:"MATCHED" expecting1:"" expecting2:""
*)
(*
-- REMOVE DIGITS AND DASH FROM BEGGING
set myTestName to "REMOVE DIGITS AND DASH FROM BEGGING"
set myPattern1 to "/^(\\s*[0-9]+\\s*-?\\s*)"
set myPattern2 to "/^(\\s*[0-9]+\\s*-?\\s*)/m"
set mySourceA to "001 Come Together"
set mySourceB to "123123123 - Believe"
set myReplace to ""
set myTestA1 to my findInString:mySourceA withPattern:myPattern1 replaceWith:myReplace
set myTestA2 to my findInString:mySourceA withPattern:myPattern2 replaceWith:myReplace
set myTestB1 to my findInString:mySourceB withPattern:myPattern1 replaceWith:myReplace
set myTestB2 to my findInString:mySourceB withPattern:myPattern2 replaceWith:myReplace
if logResults then
log ("-------------------------------------------NEW TEST START")
log {"----------------myTestName is", myTestName}
log {"myPattern1 is", myPattern1}
log {"myPattern2 is", myPattern2}
log {"mySourceA is", mySourceA}
log {"myReplace is", myReplace}
log {"myTestA1 is", myTestA1}
log {"myTestA2 is", myTestA2}
log {"mySourceB is", mySourceB}
log {"myTestB1 is", myTestB1}
log {"myTestB2 is", myTestB2}
end if
-- REMOVE THE FROM BEGGING
set myTestName to "REMOVE THE FROM BEGGING"
set myPattern1 to "/^the\\W/mi"
set myPattern2 to ""
set mySourceA to "The Beatles"
set mySourceB to "Adam and the Ants"
set myReplace to ""
set myTestA1 to my findInString:mySourceA withPattern:myPattern1 replaceWith:myReplace
set myTestA2 to my findInString:mySourceB withPattern:myPattern1 replaceWith:myReplace
if logResults then
log ("-------------------------------------------NEW TEST START")
log {"----------------myTestName is", myTestName}
log {"myPattern1 is", myPattern1}
log {"myPattern2 is", myPattern2}
log {"mySourceA is", mySourceA}
log {"mySourceB is", mySourceB}
log {"myReplace is", myReplace}
log {"myTestA1 is", myTestA1}
log {"myTestA2 is", myTestA2}
end if
((?:Red)?\b(?:Hot)?\b(?:Chili)?\b(?:Peppers)?\b)
-- MATCH WHOLE WORD - EG WORK, hello
set myTestName to "MATCH WHOLE WORD - EG WORK, hello"
set myPattern1 to "\\b(\\w*work\\w*)\\b"
set myPattern2 to "\\b(\\w*hello\\w*)\\b"
set mySourceA to "hello 'worked? hello working all works and \"worked with \""
set mySourceB to ""
set myReplace to "XXXXX"
set myTestA1 to my findInString:mySourceA withPattern:myPattern1 replaceWith:myReplace
set myTestA2 to my findInString:mySourceA withPattern:myPattern2 replaceWith:myReplace
if logResults then
log ("-------------------------------------------NEW TEST START")
log {"----------------myTestName is", myTestName}
log {"myPattern1 is", myPattern1}
log {"myPattern2 is", myPattern2}
log {"mySourceA is", mySourceA}
log {"mySourceB is", mySourceB}
log {"myReplace is", myReplace}
log {"myTestA1 is", myTestA1}
log {"myTestA2 is", myTestA2}
end if
-- REMOVE BRACKETS AND BETWEETN
set myTestName to "REMOVE BRACKETS AND BETWEETN"
set myPattern1 to "(\\s*?\\(.+?\\)\\s*)+"
set myPattern2 to "(\\W?(\\(|\\[|\\{).+?(\\)|\\]|\\})\\W?)+" -- also remove { and [
set mySourceA to "Blah (blah1) (blah 2) me to (plus) check{all the men) and the [alll them]"
set mySourceB to ""
set myReplace to " "
set myTestA1 to my findInString:mySourceA withPattern:myPattern1 replaceWith:myReplace
set myTestA2 to my findInString:mySourceA withPattern:myPattern2 replaceWith:myReplace
if logResults then
log ("-------------------------------------------NEW TEST START")
log {"----------------myTestName is", myTestName}
log {"myPattern1 is", myPattern1}
log {"myPattern2 is", myPattern2}
log {"mySourceA is", mySourceA}
log {"mySourceB is", mySourceB}
log {"myReplace is", myReplace}
log {"myTestA1 is", myTestA1}
log {"myTestA2 is", myTestA2}
end if
-- REMOVE DASH TO END
set myTestName to "REMOVE DASH TO END"
set myPattern1 to "( -\\s?(.*))"
set myPattern2 to "(\\s+-\\s?(.*))" -- also remove { and [
set mySourceA to "Blah (blah1) -me to (plus) check{all the men) and the [alll them]"
set mySourceB to ""
set myReplace to ""
set myTestA1 to my findInString:mySourceA withPattern:myPattern1 replaceWith:myReplace
set myTestA2 to my findInString:mySourceA withPattern:myPattern2 replaceWith:myReplace
if logResults then
log ("-------------------------------------------NEW TEST START")
log {"----------------myTestName is", myTestName}
log {"myPattern1 is", myPattern1}
log {"myPattern2 is", myPattern2}
log {"mySourceA is", mySourceA}
log {"mySourceB is", mySourceB}
log {"myReplace is", myReplace}
log {"myTestA1 is", myTestA1}
log {"myTestA2 is", myTestA2}
end if
-- CAPTURE YEAR 19xx or 20xx or 21xx
set myTestName to "CAPTURE YEAR 19xx or 20xx or 21xx"
set myPattern1 to "/\\s?(?:\\(|\\[|\\{)?([1-2][0|1|9][0-9]{2})(?:\\)|\\]|\\})?\\s?/i"
set myPattern2 to "\\s?(?:\\(|\\[|\\{)?([1-2][0|1|9][0-9]{2})(?:\\)|\\]|\\})?\\s?\\-?\\s?(.*)\\s\\[.*(HD).*\\]"
set mySourceA to "1971 - Paul Simon [24bit 96kHz 2010 HDtracks FLAC]"
set mySourceB to "1923 Rolling Stones"
set myReplace to "$2 $3 ($1)"
set myTestExpect1 to "Paul Simon HD (1971)"
set expectResults2 to "Rolling Stones (1923)"
set myTestA1 to my findInString:mySourceA withPattern:myPattern1 replaceWith:myReplace
set myTestA2 to my findInString:mySourceB withPattern:myPattern1 replaceWith:myReplace
if logResults then
log ("-------------------------------------------NEW TEST START")
log {"----------------myTestName is", myTestName}
log {"myPattern1 is", myPattern1}
log {"myPattern2 is", myPattern2}
log {"mySourceA is", mySourceA}
log {"mySourceB is", mySourceB}
log {"myReplace is", myReplace}
log {"myTestA1 is", myTestA1}
log {"myTestA2 is", myTestA2}
end if
-- CAPTURE YEAR V2
set myTestName to "CAPTURE YEAR V2"
set myPattern1 to "/\\s?(?:\\(|\\[|\\{)?([1-2][0|1|9][0-9]{2})(?:\\)|\\]|\\})?\\W+/i"
set myPattern2 to ""
set mySourceA to "2009 - The Rolling Stones - Great Album"
set mySourceB to ""
set myReplace to "$`$' ($1)"
set expectResults1 to "The Rolling Stones - Great Album (2009)"
set myTestA1 to my findInString:mySourceA withPattern:myPattern1 replaceWith:myReplace
set myTestA2 to ""
if logResults then
log ("-------------------------------------------NEW TEST START")
log {"----------------myTestName is", myTestName}
log {"myPattern1 is", myPattern1}
log {"myPattern2 is", myPattern2}
log {"mySourceA is", mySourceA}
log {"mySourceB is", mySourceB}
log {"myReplace is", myReplace}
log {"myTestA1 is", myTestA1}
log {"myTestA2 is", myTestA2}
end if
-- CAPTURE YEAR V3 More Complete With Capture Groups
set myTestName to "CAPTURE YEAR V3 More Complete With Capture Groups"
set myPattern1 to "/(.*)\\s?(?:\\(|\\[|\\{)?([1-2][0|1|9][0-9]{2})(?:\\)|\\]|\\})?\\W+(.*)/i"
set myPattern2 to ""
set mySourceA to "2009 - The Rolling Stones - Great Album"
set mySourceB to ""
set myReplace to "$1$3 ($2)"
set expectResults1 to "The Rolling Stones - Great Album (2009)"
set myTestA1 to my findInString:mySourceA withPattern:myPattern1 replaceWith:myReplace
set myTestA2 to ""
if logResults then
log ("-------------------------------------------NEW TEST START")
log {"----------------myTestName is", myTestName}
log {"myPattern1 is", myPattern1}
log {"myPattern2 is", myPattern2}
log {"mySourceA is", mySourceA}
log {"mySourceB is", mySourceB}
log {"myReplace is", myReplace}
log {"myTestA1 is", myTestA1}
log {"myTestA2 is", myTestA2}
end if
-- REMOVE DASH TO END
set myTestName to "REMOVE DASH TO END"
set myPattern1 to "( -\\s?(.*))"
set myPattern2 to "(\\s+-\\s?(.*))" -- also remove { and [
set mySourceA to "Blah (blah1) -me to (plus) check{all the men) and the [alll them]"
set mySourceB to ""
set myReplace to ""
set myTestA1 to my findInString:mySourceA withPattern:myPattern1 replaceWith:myReplace
set myTestA2 to my findInString:mySourceA withPattern:myPattern2 replaceWith:myReplace
if logResults then
log ("-------------------------------------------NEW TEST START")
log {"----------------myTestName is", myTestName}
log {"myPattern1 is", myPattern1}
log {"myPattern2 is", myPattern2}
log {"mySourceA is", mySourceA}
log {"mySourceB is", mySourceB}
log {"myReplace is", myReplace}
log {"myTestA1 is", myTestA1}
log {"myTestA2 is", myTestA2}
end if
-- MUSIC SPECIFIC
-- GENRE REFORMAT
set myTestName to "GENRE REFORMAT"
--set myPattern1 to "(\\s?,\\s?)|(?:\\b)(\\s?[/]\\s?)(?:\\b)" -- this works
set myPattern1 to "(^|\\W+)?(,|\\/)(\\W+|$)?" -- this works and also does not replace dashes
set myPattern2 to "(^|\\W+)?(,|\\/|\\s)(\\W+|$)?" -- this works and also replaces spaces with dash
set mySourceA to "futureSoul/RnB Disco Boogie, Funk"
set mySourceB to ""
set myReplace to " - "
set expectResults1 to "futureSoul - RnB - Disco - Boogie - Funk"
set myTestA1 to my findInString:mySourceA withPattern:myPattern1 replaceWith:myReplace
set myTestA2 to my findInString:mySourceA withPattern:myPattern2 replaceWith:myReplace
if logResults then
log ("-------------------------------------------NEW TEST START")
log {"----------------myTestName is", myTestName}
log {"myPattern1 is", myPattern1}
log {"myPattern2 is", myPattern2}
log {"mySourceA is", mySourceA}
log {"mySourceB is", mySourceB}
log {"myReplace is", myReplace}
log {"myTestA1 is", myTestA1}
log {"myTestA2 is", myTestA2}
end if
*)
-- MUSIC SPECIFIC
(*
-- VS REPLACE
set myTestName to "VS REPLACE"
set myPattern1 to "(^|\\W+)(vs|versus)(\\W+|$)"
set myPattern2 to "/(^|\\W+)(vs|versus)(\\W+|$)/mi"
set mySourceA to "this is kerry vs. the world and her versus everything and dj vs me and vse "
set mySourceB to ""
set myReplace to " & "
set myTestExpect to "this is kerry & the world and her & everything and dj & me and vse "
*)
-- *myTestA1 "this is kerry & the world and her & everything and dj & me and vse "*)
-- (*myTestA2 is, (NSString) "this is kerry vs. the world and her versus everything and dj vs me and vse "*)
(*
-- SINGLE ARTIST MATCH
-- (?:(^the\\s)|(\\,\\s?)|^)(Eagles)(?:$|\\,)
set myTestName to "SINGLE ARTIST MATCH"
set myPattern1 to "(?:(^the\\s)|(\\,\\s?)|^)(Eagles)(?:$|\\,)"
set myPattern2 to "/(^|\\W+)(vs|versus)(\\W+|$)/mi"
set mySourceA to "The Eagles of"
set mySourceB to "CCR, Eagles"
set myReplace to "XXXXXXXXXXXX"
*)