Regex
Advanced regular expressions for Swift
Goals
 Regex library was mainly introduced to fulfill the needs of Swift Express - web application server side framework for Swift.
Still we hope it will be useful for everybody else.
Features
-  Deep Integration with Swift 
  
-  
=~operator support -  Swift Pattern Matching (aka 
switchoperator) support 
 -  
 - Named groups
 - Match checking
 - Extraction/Search functions
 -  Replace functions 
  
- With a pattern
 - With custom replacing function
 
 -  Splitting with a Regular Expression 
  
- Simple
 - With groups
 
 - String extensions
 -  Supports grapheme clusters 
đ¨âđŠâđ§  
Extra
Path to Regex converter is available as a separate library here: PathToRegex
This one allows using path patterns like /folder/*/:file.txt or /route/:one/:two to be converted to Regular Expressions and matched against strings.
Getting started
Installation
Package Manager
Add the following dependency to your Package.swift:
.Package(url: "https://github.com/crossroadlabs/Regex.git", majorVersion: 1) 
Run swift build and build your app.
CocoaPods
Add the following to your Podfile:
pod 'CrossroadRegex' 
Make sure that you are integrating your dependencies using frameworks: add use_frameworks! to your Podfile. Then run pod install.
Carthage
Add the following to your Cartfile:
github "crossroadlabs/Regex"
 
Run carthage update and follow the steps as described in Carthage's README.
Manually
- Download and drop 
/Regexfolder in your project. - Congratulations!
 
Examples
Hello Regex:
All the lines below are identical and represent simple matching. All operators and matches function return Bool
//operator way, can match either regex or string containing pattern
"l321321alala" =~ "(.+?)([123]*)(.*)".r
"l321321alala" =~ "(.+?)([123]*)(.*)"
//similar function
"(.+?)([123]*)(.*)".r!.matches("l321321alala") 
Operator !~ returns true if expression does NOT match:
"l321321alala" !~ "(.+?)([123]*)(.*)".r
"l321321alala" !~ "(.+?)([123]*)(.*)"
//both return false 
Swift Pattern Matching (aka switch keyword)
 
Regex provides very deep integration with Swift and can be used with the switch keyword in the following way:
let letter = "a"
let digit = "1"
let other = "!"
//you just put your string is a regular Swift's switch to match to regular expressions
switch letter {
	//note .r after the string literal of the pattern
	case "\\d".r: print("digit")
	case "[a-z]".r: print("letter")
	default: print("bizarre symbol")
}
switch digit {
	case "\\d".r: print("digit")
	case "[a-z]".r: print("letter")
	default: print("bizarre symbol")
}
switch other {
	//note .r after the string literal of the pattern
	case "\\d".r: print("digit")
	case "[a-z]".r: print("letter")
	default: print("bizarre symbol")
} 
The output of the code above will be:
letter
digit
bizarre symbol
 
Accessing groups:
// strings can be converted to regex in Scala style .r property of a string
let digits = "(.+?)([123]*)(.*)".r?.findFirst(in: "l321321alala")?.group(at: 2)
// digits is "321321" here 
Named groups:
let regex:RegexType = try Regex(pattern:"(.+?)([123]*)(.*)",
                                        groupNames:"letter", "digits", "rest")
let match = regex.findFirst(in: "l321321alala")
if let match = match {
	let letter = match.group(named: "letter")
	let digits = match.group(named: "digits")
	let rest = match.group(named: "rest")
	//do something with extracted data
} 
Replace:
let replaced = "(.+?)([123]*)(.*)".r?.replaceAll(in: "l321321alala", with: "$1-$2-$3")
//replaced is "l-321321-alala" 
Replace with custom replacer function:
let replaced = "(.+?)([123]+)(.+?)".r?.replaceAll(in: "l321321la321a") { match in
	if match.group(at: 1) == "l" {
		return nil
	} else {
		return match.matched.uppercaseString
	}
}
//replaced is "l321321lA321A" 
Split:
In the following example, split() looks for 0 or more spaces followed by a semicolon followed by 0 or more spaces and, when found, removes the spaces from the string. nameList is the array returned as a result of split().
let names = "Harry Trump ;Fred Barney; Helen Rigby ; Bill Abel ;Chris Hand"
let nameList = names.split(using: "\\s*;\\s*".r)
//name list contains ["Harry Trump", "Fred Barney", "Helen Rigby", "Bill Abel", "Chris Hand"] 
Split with groups:
If separator contains capturing parentheses, matched results are returned in the array.
let myString = "Hello 1 word. Sentence number 2."
let splits = myString.split(using: "(\\d)".r)
//splits contains ["Hello ", "1", " word. Sentence number ", "2", "."] 
Changelog
You can view the CHANGELOG as a separate document here.
Contributing
To get started, sign the Contributor License Agreement.

 by Crossroad Labs