Search code examples
regexswiftfoundationnsregularexpression

What is .WithTransparentBounds?


I have a need to collapse multiple whitespace into one space. After digging around in Foundation Framework NSString Class Reference, Google, and stackoverflow, I found enough information and sample code to get me to

var myString = "Snoopy      Doogitz"

if let regex = try? NSRegularExpression( pattern: "\\s+", options: [] ) {
    let modString = regex.stringByReplacingMatchesInString( myString, options: .WithTransparentBounds, range: NSMakeRange( 0, myString.characters.count ), withTemplate: " ")
    print( modString )
}

which works.

However, I can't seem to find an explanation in documentation for .WithTransparentBounds

If I remove it from my code

var myString = "Snoopy      Doogitz"

if let regex = try? NSRegularExpression( pattern: "\\s+", options: [] ) {
    let modString = regex.stringByReplacingMatchesInString( myString, options: [], range: NSMakeRange( 0, myString.characters.count ), withTemplate: " ")
    print( modString )
}

That works just fine, too. But before I leave this, I'd love to know what the option .WithTransparentBounds actually means, for someday I might need it?

Thanks in advance!


Solution

  • Quoting from the comment in NSRegularExpression.h:

    NSMatchingAnchored, NSMatchingWithTransparentBounds, and NSMatchingWithoutAnchoringBounds can apply to any match or replace method. If NSMatchingAnchored is specified, matches are limited to those at the start of the search range. If NSMatchingWithTransparentBounds is specified, matching may examine parts of the string beyond the bounds of the search range, for purposes such as word boundary detection, lookahead, etc. If NSMatchingWithoutAnchoringBounds is specified, ^ and $ will not automatically match the beginning and end of the search range (but will still match the beginning and end of the entire string). NSMatchingWithTransparentBounds and NSMatchingWithoutAnchoringBounds have no effect if the search range covers the entire string.

    Here's an example that illustrates the difference when you include WithTransparentBounds:

    let str = "foobarbaz"
    
    let re = try! NSRegularExpression(pattern: "bar\\b", options: [])
    re.numberOfMatchesInString(str, options: .WithTransparentBounds, range: NSRange(location: 0, length: 9)) // returns 0
    re.numberOfMatchesInString(str, options: .WithTransparentBounds, range: NSRange(location: 3, length: 3)) // returns 0
    re.numberOfMatchesInString(str, options: [], range: NSRange(location: 3, length: 3)) // returns 1