Repository: cezheng/PySwiftyRegex
Branch: master
Commit: 4e51e6162f57
Files: 21
Total size: 88.9 KB
Directory structure:
gitextract_eolrdn6l/
├── .gitignore
├── .swift-version
├── .travis.yml
├── LICENSE
├── PySwiftyRegex/
│ ├── Info.plist
│ ├── PySwiftyRegex.h
│ └── PySwiftyRegex.swift
├── PySwiftyRegex.podspec
├── PySwiftyRegex.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata/
│ └── xcschemes/
│ └── PySwiftyRegex.xcscheme
├── PySwiftyRegexTests/
│ ├── Info.plist
│ ├── ReMatchObjectTests.swift
│ ├── ReRegexObjectTests.swift
│ ├── ReTests.swift
│ └── TestHelpers.swift
├── README-ja.md
├── README-ko.md
├── README-zh.md
└── README.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## Build generated
build/
DerivedData
## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
## Other
*.xccheckout
*.moved-aside
*.xcuserstate
*.xcscmblueprint
## Obj-C/Swift specific
*.hmap
*.ipa
# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
#
# Pods/
# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts
Carthage/Build
# OSX
.DS_Store
================================================
FILE: .swift-version
================================================
4.0
================================================
FILE: .travis.yml
================================================
language: objective-c
os: osx
osx_image: xcode10.3
env:
global:
- XCODEPROJ="PySwiftyRegex.xcodeproj"
- SCHEME="PySwiftyRegex"
matrix:
- DESTINATION="platform=OS X,arch=x86_64" SDK="macosx" ACTION="test"
- DESTINATION="platform=iOS Simulator,name=iPhone X" SDK="iphonesimulator" ACTION="test"
- DESTINATION="platform=tvOS Simulator,name=Apple TV 4K" SDK="appletvsimulator" ACTION="test"
- DESTINATION="name=Apple Watch Series 4 - 40mm" SDK="watchsimulator" ACTION="build"
script:
- xcode-select -p
- xcodebuild -project "$XCODEPROJ" -scheme "$SCHEME" -destination "$DESTINATION" -sdk $SDK $ACTION
================================================
FILE: LICENSE
================================================
Copyright (c) 2015 Ce Zheng
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: PySwiftyRegex/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2015ー2016 Ce Zheng. All rights reserved.</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
================================================
FILE: PySwiftyRegex/PySwiftyRegex.h
================================================
// PySwiftyRegex.h
// Copyright (c) 2015ー2016 Ce Zheng
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <Foundation/Foundation.h>
//! Project version number for PySwiftyRegex.
FOUNDATION_EXPORT double PySwiftyRegexVersionNumber;
//! Project version string for PySwiftyRegex.
FOUNDATION_EXPORT const unsigned char PySwiftyRegexVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <PySwiftyRegex/PublicHeader.h>
================================================
FILE: PySwiftyRegex/PySwiftyRegex.swift
================================================
// PySwiftyRegex.swift
// Copyright (c) 2015ー2016 Ce Zheng
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import Foundation
/**
* Counterpart of Python's re module, but as a class.
*/
public class re {
// MARK: - re methods
/**
Compile a regular expression pattern into a RegexObject object, which can be used for matching using its match() and search() methods, described below.
See https://docs.python.org/2/library/re.html#re.compile
- parameter pattern: regular expression pattern string
- parameter flags: NSRegularExpressionOptions value
- returns: The created RegexObject object. If the pattern is invalid, RegexObject.isValid is false, and all methods have a default return value.
*/
public static func compile(_ pattern: String, flags: RegexObject.Flag = []) -> RegexObject {
return RegexObject(pattern: pattern, flags: flags)
}
/**
Scan through string looking for the first location where the regular expression pattern produces a match, and return a corresponding MatchObject instance.
See https://docs.python.org/2/library/re.html#re.search
- parameter pattern: regular expression pattern string
- parameter string: string to be searched
- parameter flags: NSRegularExpressionOptions value
- returns: Corresponding MatchObject instance. Return nil if no position in the string matches the pattern or pattern is invalid; note that this is different from finding a zero-length match at some point in the string.
*/
public static func search(_ pattern: String, _ string: String, flags: RegexObject.Flag = []) -> MatchObject? {
return re.compile(pattern, flags: flags).search(string)
}
/**
If zero or more characters at the beginning of string match the regular expression pattern, return a corresponding MatchObject instance.
See https://docs.python.org/2/library/re.html#re.match
- parameter pattern: regular expression pattern string
- parameter string: string to be searched
- parameter flags: NSRegularExpressionOptions value
- returns: Corresponding MatchObject instance. Return nil if the string does not match the pattern or pattern is invalid; note that this is different from a zero-length match.
*/
public static func match(_ pattern: String, _ string: String, flags: RegexObject.Flag = []) -> MatchObject? {
return re.compile(pattern, flags: flags).match(string)
}
/**
Split string by the occurrences of pattern. If capturing parentheses are used in pattern, then the text of all groups in the pattern are also returned as part of the resulting list. If maxsplit is nonzero, at most maxsplit splits occur, and the remainder of the string is returned as the final element of the list.
See https://docs.python.org/2/library/re.html#re.split
- parameter pattern: regular expression pattern string
- parameter string: string to be splitted
- parameter maxsplit: maximum number of times to split the string, defaults to 0, meaning no limit is applied
- parameter flags: NSRegularExpressionOptions value
- returns: Array of splitted strings
*/
public static func split(_ pattern: String, _ string: String, _ maxsplit: Int = 0, flags: RegexObject.Flag = []) -> [String?] {
return re.compile(pattern, flags: flags).split(string, maxsplit)
}
/**
Return all non-overlapping matches of pattern in string, as a list of strings. The string is scanned left-to-right, and matches are returned in the order found. Empty matches are included in the result unless they touch the beginning of another match.
See https://docs.python.org/2/library/re.html#re.findall
- parameter pattern: regular expression pattern string
- parameter string: string to be searched
- parameter flags: NSRegularExpressionOptions value
- returns: Array of matched substrings
*/
public static func findall(_ pattern: String, _ string: String, flags: RegexObject.Flag = []) -> [String] {
return re.compile(pattern, flags: flags).findall(string)
}
/**
Return an array of MatchObject instances over all non-overlapping matches for the RE pattern in string. The string is scanned left-to-right, and matches are returned in the order found. Empty matches are included in the result unless they touch the beginning of another match.
See https://docs.python.org/2/library/re.html#re.finditer
- parameter pattern: regular expression pattern string
- parameter string: string to be searched
- parameter flags: NSRegularExpressionOptions value
- returns: Array of match results as MatchObject instances
*/
public static func finditer(_ pattern: String, _ string: String, flags: RegexObject.Flag = []) -> [MatchObject] {
return re.compile(pattern, flags: flags).finditer(string)
}
/**
Return the string obtained by replacing the leftmost non-overlapping occurrences of pattern in string by the replacement repl. If the pattern isn’t found, string is returned unchanged. Different from python, passing a repl as a closure is not supported.
See https://docs.python.org/2/library/re.html#re.sub
- parameter pattern: regular expression pattern string
- parameter repl: replacement string
- parameter string: string to be searched and replaced
- parameter count: maximum number of times to perform replace operations to the string
- parameter flags: NSRegularExpressionOptions value
- returns: replaced string
*/
public static func sub(_ pattern: String, _ repl: String, _ string: String, _ count: Int = 0, flags: RegexObject.Flag = []) -> String {
return re.compile(pattern, flags: flags).sub(repl, string, count)
}
/**
Perform the same operation as sub(), but return a tuple (new_string, number_of_subs_made) as (String, Int)
See https://docs.python.org/2/library/re.html#re.subn
- parameter pattern: regular expression pattern string
- parameter repl: replacement string
- parameter string: string to be searched and replaced
- parameter count: maximum number of times to perform replace operations to the string
- parameter flags: NSRegularExpressionOptions value
- returns: a tuple (new_string, number_of_subs_made) as (String, Int)
*/
public static func subn(_ pattern: String, _ repl: String, _ string: String, _ count: Int = 0, flags: RegexObject.Flag = []) -> (String, Int) {
return re.compile(pattern, flags: flags).subn(repl, string, count)
}
// MARK: - RegexObject
/**
* Counterpart of Python's re.RegexObject
*/
public class RegexObject {
/// Typealias for NSRegularExpressionOptions
public typealias Flag = NSRegularExpression.Options
/// Whether this object is valid or not
public var isValid: Bool {
return regex != nil
}
/// Pattern used to construct this RegexObject
public let pattern: String
private let regex: NSRegularExpression?
/// Underlying NSRegularExpression Object
public var nsRegex: NSRegularExpression? {
return regex
}
/// NSRegularExpressionOptions used to contructor this RegexObject
public var flags: Flag {
return regex?.options ?? []
}
/// Number of capturing groups
public var groups: Int {
return regex?.numberOfCaptureGroups ?? 0
}
/**
Create A re.RegexObject Instance
- parameter pattern: regular expression pattern string
- parameter flags: NSRegularExpressionOptions value
- returns: The created RegexObject object. If the pattern is invalid, RegexObject.isValid is false, and all methods have a default return value.
*/
public required init(pattern: String, flags: Flag = []) {
self.pattern = pattern
do {
self.regex = try NSRegularExpression(pattern: pattern, options: flags)
} catch let error as NSError {
self.regex = nil
debugPrint(error)
}
}
/**
Scan through string looking for a location where this regular expression produces a match, and return a corresponding MatchObject instance. Return nil if no position in the string matches the pattern; note that this is different from finding a zero-length match at some point in the string.
See https://docs.python.org/2/library/re.html#re.RegexObject.search
- parameter string: string to be searched
- parameter pos: position in string where the search is to start, defaults to 0
- parameter endpos: position in string where the search it to end (non-inclusive), defaults to nil, meaning the end of the string. If endpos is less than pos, no match will be found.
- parameter options: NSMatchOptions value
- returns: search result as MatchObject instance if a match is found, otherwise return nil
*/
public func search(_ string: String, _ pos: Int = 0, _ endpos: Int? = nil, options: NSRegularExpression.MatchingOptions = []) -> MatchObject? {
guard let regex = regex else {
return nil
}
let start = pos > 0 ?pos :0
let end = endpos ?? string.utf16.count
let length = max(0, end - start)
let range = NSRange(location: start, length: length)
if let match = regex.firstMatch(in: string, options: options, range: range) {
return MatchObject(string: string, match: match)
}
return nil
}
/**
If zero or more characters at the beginning of string match this regular expression, return a corresponding MatchObject instance. Return nil if the string does not match the pattern; note that this is different from a zero-length match.
See https://docs.python.org/2/library/re.html#re.RegexObject.match
- parameter string: string to be matched
- parameter pos: position in string where the search is to start, defaults to 0
- parameter endpos: position in string where the search it to end (non-inclusive), defaults to nil, meaning the end of the string. If endpos is less than pos, no match will be found.
- returns: match result as MatchObject instance if a match is found, otherwise return nil
*/
public func match(_ string: String, _ pos: Int = 0, _ endpos: Int? = nil) -> MatchObject? {
return search(string, pos, endpos, options: [.anchored])
}
/**
Identical to the re.split() function, using the compiled pattern.
See https://docs.python.org/2/library/re.html#re.RegexObject.split
- parameter string: string to be splitted
- parameter maxsplit: maximum number of times to split the string, defaults to 0, meaning no limit is applied
- returns: Array of splitted strings
*/
public func split(_ string: String, _ maxsplit: Int = 0) -> [String?] {
guard let regex = regex else {
return []
}
var splitsLeft = maxsplit == 0 ? Int.max : (maxsplit < 0 ? 0 : maxsplit)
let range = NSRange(location: 0, length: string.utf16.count)
var results = [String?]()
var start = string.startIndex
var end = string.startIndex
regex.enumerateMatches(in: string, options: [], range: range) { result, _, stop in
if splitsLeft <= 0 {
stop.pointee = true
return
}
guard let result = result, result.range.length > 0 else {
return
}
end = string.index(string.startIndex, offsetBy: result.range.location)
results.append(String(string[start..<end]))
if regex.numberOfCaptureGroups > 0 {
results += MatchObject(string: string, match: result).groups()
}
splitsLeft -= 1
start = string.index(end, offsetBy: result.range.length)
}
if start <= string.endIndex {
results.append(String(string[start..<string.endIndex]))
}
return results
}
/**
Similar to the re.findall() function, using the compiled pattern, but also accepts optional pos and endpos parameters that limit the search region like for match().
See https://docs.python.org/2/library/re.html#re.RegexObject.findall
- parameter string: string to be matched
- parameter pos: position in string where the search is to start, defaults to 0
- parameter endpos: position in string where the search it to end (non-inclusive), defaults to nil, meaning the end of the string. If endpos is less than pos, no match will be found.
- returns: Array of matched substrings
*/
public func findall(_ string: String, _ pos: Int = 0, _ endpos: Int? = nil) -> [String] {
return finditer(string, pos, endpos).map { $0.group()! }
}
/**
Similar to the re.finditer() function, using the compiled pattern, but also accepts optional pos and endpos parameters that limit the search region like for match().
https://docs.python.org/2/library/re.html#re.RegexObject.finditer
- parameter string: string to be matched
- parameter pos: position in string where the search is to start, defaults to 0
- parameter endpos: position in string where the search it to end (non-inclusive), defaults to nil, meaning the end of the string. If endpos is less than pos, no match will be found.
- returns: Array of match results as MatchObject instances
*/
public func finditer(_ string: String, _ pos: Int = 0, _ endpos: Int? = nil) -> [MatchObject] {
guard let regex = regex else {
return []
}
let start = pos > 0 ?pos :0
let end = endpos ?? string.utf16.count
let length = max(0, end - start)
let range = NSRange(location: start, length: length)
return regex.matches(in: string, options: [], range: range).map { MatchObject(string: string, match: $0) }
}
/**
Identical to the re.sub() function, using the compiled pattern.
See https://docs.python.org/2/library/re.html#re.RegexObject.sub
- parameter repl: replacement string
- parameter string: string to be searched and replaced
- parameter count: maximum number of times to perform replace operations to the string
- returns: replaced string
*/
public func sub(_ repl: String, _ string: String, _ count: Int = 0) -> String {
return subn(repl, string, count).0
}
/**
Identical to the re.subn() function, using the compiled pattern.
See https://docs.python.org/2/library/re.html#re.RegexObject.subn
- parameter repl: replacement string
- parameter string: string to be searched and replaced
- parameter count: maximum number of times to perform replace operations to the string
- returns: a tuple (new_string, number_of_subs_made) as (String, Int)
*/
public func subn(_ repl: String, _ string: String, _ count: Int = 0) -> (String, Int) {
guard let regex = regex else {
return (string, 0)
}
let range = NSRange(location: 0, length: string.utf16.count)
let mutable = NSMutableString(string: string)
let maxCount = count == 0 ? Int.max : (count > 0 ? count : 0)
var n = 0
var offset = 0
regex.enumerateMatches(in: string, options: [], range: range) { result, _, stop in
if maxCount <= n {
stop.pointee = true
return
}
if let result = result {
n += 1
let resultRange = NSRange(location: result.range.location + offset, length: result.range.length)
let lengthBeforeReplace = mutable.length
regex.replaceMatches(in: mutable, options: [], range: resultRange, withTemplate: repl)
offset += mutable.length - lengthBeforeReplace
}
}
return (mutable as String, n)
}
}
// MARK: - MatchObject
/**
* Counterpart of Python's re.MatchObject
*/
public final class MatchObject {
/// String matched
public let string: String
/// Underlying NSTextCheckingResult
public let match: NSTextCheckingResult
init(string: String, match: NSTextCheckingResult) {
self.string = string
self.match = match
}
/**
Return the string obtained by doing backslash substitution on the template string template, as done by the sub() method.
Note that named backreferences in python is not supported here since NSRegularExpression does not have this feature.
See https://docs.python.org/2/library/re.html#re.MatchObject.expand
- parameter template: regular expression template decribing the expanded format
- returns: expanded string
*/
public func expand(_ template: String) -> String {
guard let regex = match.regularExpression else {
return ""
}
return regex.replacementString(for: match, in: string, offset: 0, template: template)
}
/**
Returns one subgroup of the match. If the group number is negative or larger than the number of groups defined in the pattern, nil returned. If a group is contained in a part of the pattern that did not match, the corresponding result is nil. If a group is contained in a part of the pattern that matched multiple times, the last match is returned.
Note that different from python's group function this function does not accept multiple arguments due to ambiguous syntax. If you would like to use multiple arguments pass in an array instead.
See https://docs.python.org/2/library/re.html#re.MatchObject.group
- parameter index: group index, defaults to 0, meaning the entire matching string
- returns: string of the matching group
*/
public func group(_ index: Int = 0) -> String? {
guard let range = span(index), range.lowerBound < string.endIndex else {
return nil
}
return String(string[range])
}
/**
Returns one or more subgroups of the match. If a group number is negative or larger than the number of groups defined in the pattern, nil is inserted at the relevant index of the returned array. If a group is contained in a part of the pattern that did not match, the corresponding result is None. If a group is contained in a part of the pattern that matched multiple times, the last match is returned.
See https://docs.python.org/2/library/re.html#re.MatchObject.group
- parameter indexes: array of group indexes to get
- returns: array of strings of the matching groups
*/
public func group(_ indexes: [Int]) -> [String?] {
return indexes.map { group($0) }
}
/**
Return an array containing all the subgroups of the match, from 1 up to however many groups are in the pattern. The default argument is used for groups that did not participate in the match.
Note that python version of this function returns a tuple while this one returns an array due to the fact that swift cannot specify a variadic tuple as return value.
See https://docs.python.org/2/library/re.html#re.MatchObject.groups
- parameter defaultValue: default value string
- returns: array of all matching subgroups as String
*/
public func groups(_ defaultValue: String) -> [String] {
return (1..<match.numberOfRanges).map { group($0) ?? defaultValue }
}
/**
Return an array containing all the subgroups of the match, from 1 up to however many groups are in the pattern. For groups that did not participate in the match, nil is inserted at the relevant index of the return array.
Note that python version of this function returns a tuple while this one returns an array due to the fact that swift cannot specify a variadic tuple as return value.
See https://docs.python.org/2/library/re.html#re.MatchObject.groups
- returns: array of all matching subgroups as String? (nil when relevant optional capture group is not matched)
*/
public func groups() -> [String?] {
return (1..<match.numberOfRanges).map { group($0) }
}
/**
Return the range of substring matched by group; group defaults to zero (meaning the whole matched substring). Return nil if paremeter is invalid or group exists but did not contribute to the match.
See https://docs.python.org/2/library/re.html#re.MatchObject.span
- parameter index: group index
- returns: range of matching group substring
*/
public func span(_ index: Int = 0) -> Range<String.Index>? {
if index >= match.numberOfRanges {
return nil
}
let nsrange = match.range(at: index)
if nsrange.location == NSNotFound {
return string.endIndex..<string.endIndex
}
let startIndex16 = string.utf16.index(string.startIndex, offsetBy: nsrange.location)
let endIndex16 = string.utf16.index(startIndex16, offsetBy: nsrange.length)
return (String.Index(startIndex16, within: string) ?? string.endIndex)..<(String.Index(endIndex16, within: string) ?? string.endIndex)
}
}
}
================================================
FILE: PySwiftyRegex.podspec
================================================
Pod::Spec.new do |s|
s.name = "PySwiftyRegex"
s.version = "3.0.0"
s.license = "MIT"
s.summary = "Easily deal with Regex in Swift in a Pythonic way"
s.homepage = "https://github.com/cezheng/PySwiftyRegex"
s.social_media_url = "https://twitter.com/AdamoCheng"
s.author = { "Ce Zheng" => "cezheng.cs@gmail.com" }
s.source = { :git => "https://github.com/cezheng/PySwiftyRegex.git", :tag => s.version }
s.ios.deployment_target = "8.0"
s.osx.deployment_target = "10.9"
s.watchos.deployment_target = "2.0"
s.tvos.deployment_target = "9.0"
s.source_files = "PySwiftyRegex/*.swift"
s.requires_arc = true
end
================================================
FILE: PySwiftyRegex.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
0CEBDD2E1B39B8C4003A40BB /* PySwiftyRegex.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CEBDD241B39B8C3003A40BB /* PySwiftyRegex.framework */; };
0CEBDD3B1B39BAC3003A40BB /* PySwiftyRegex.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CEBDCE11B39B2FB003A40BB /* PySwiftyRegex.h */; settings = {ATTRIBUTES = (Public, ); }; };
0CEBDD3C1B39C54B003A40BB /* ReRegexObjectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CEBDCED1B39B2FC003A40BB /* ReRegexObjectTests.swift */; };
0CEBDD3D1B39C54B003A40BB /* ReMatchObjectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CEBDCFA1B39B48C003A40BB /* ReMatchObjectTests.swift */; };
0CEBDD3E1B39C5EC003A40BB /* PySwiftyRegex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CEBDCF81B39B312003A40BB /* PySwiftyRegex.swift */; };
795691DB1C74A9B9002B1CA4 /* ReTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C383C3A1B50CFF5008837A8 /* ReTests.swift */; };
795691DE1C74AACB002B1CA4 /* TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 795691DC1C74AACB002B1CA4 /* TestHelpers.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
0CEBDD2F1B39B8C4003A40BB /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0CEBDCD51B39B2FB003A40BB /* Project object */;
proxyType = 1;
remoteGlobalIDString = 0CEBDD231B39B8C3003A40BB;
remoteInfo = PySwiftyRegex;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
0C383C3A1B50CFF5008837A8 /* ReTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReTests.swift; sourceTree = "<group>"; };
0CEBDCE11B39B2FB003A40BB /* PySwiftyRegex.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PySwiftyRegex.h; sourceTree = "<group>"; };
0CEBDCE31B39B2FB003A40BB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
0CEBDCED1B39B2FC003A40BB /* ReRegexObjectTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReRegexObjectTests.swift; sourceTree = "<group>"; };
0CEBDCEF1B39B2FC003A40BB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
0CEBDCF81B39B312003A40BB /* PySwiftyRegex.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PySwiftyRegex.swift; sourceTree = "<group>"; };
0CEBDCFA1B39B48C003A40BB /* ReMatchObjectTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReMatchObjectTests.swift; sourceTree = "<group>"; };
0CEBDD241B39B8C3003A40BB /* PySwiftyRegex.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PySwiftyRegex.framework; sourceTree = BUILT_PRODUCTS_DIR; };
0CEBDD2D1B39B8C4003A40BB /* PySwiftyRegexTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PySwiftyRegexTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
795691DC1C74AACB002B1CA4 /* TestHelpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestHelpers.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
0CEBDD201B39B8C3003A40BB /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
0CEBDD2A1B39B8C4003A40BB /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
0CEBDD2E1B39B8C4003A40BB /* PySwiftyRegex.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
0CEBDCD41B39B2FB003A40BB = {
isa = PBXGroup;
children = (
0CEBDCE01B39B2FB003A40BB /* PySwiftyRegex */,
0CEBDCEC1B39B2FC003A40BB /* PySwiftyRegexTests */,
0CEBDCDF1B39B2FB003A40BB /* Products */,
);
sourceTree = "<group>";
};
0CEBDCDF1B39B2FB003A40BB /* Products */ = {
isa = PBXGroup;
children = (
0CEBDD241B39B8C3003A40BB /* PySwiftyRegex.framework */,
0CEBDD2D1B39B8C4003A40BB /* PySwiftyRegexTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
0CEBDCE01B39B2FB003A40BB /* PySwiftyRegex */ = {
isa = PBXGroup;
children = (
0CEBDCE11B39B2FB003A40BB /* PySwiftyRegex.h */,
0CEBDCF81B39B312003A40BB /* PySwiftyRegex.swift */,
0CEBDCE31B39B2FB003A40BB /* Info.plist */,
);
path = PySwiftyRegex;
sourceTree = "<group>";
};
0CEBDCEC1B39B2FC003A40BB /* PySwiftyRegexTests */ = {
isa = PBXGroup;
children = (
0C383C3A1B50CFF5008837A8 /* ReTests.swift */,
0CEBDCED1B39B2FC003A40BB /* ReRegexObjectTests.swift */,
0CEBDCFA1B39B48C003A40BB /* ReMatchObjectTests.swift */,
0CEBDCEF1B39B2FC003A40BB /* Info.plist */,
795691DC1C74AACB002B1CA4 /* TestHelpers.swift */,
);
path = PySwiftyRegexTests;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
0CEBDD211B39B8C3003A40BB /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
0CEBDD3B1B39BAC3003A40BB /* PySwiftyRegex.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
0CEBDD231B39B8C3003A40BB /* PySwiftyRegex */ = {
isa = PBXNativeTarget;
buildConfigurationList = 0CEBDD351B39B8C4003A40BB /* Build configuration list for PBXNativeTarget "PySwiftyRegex" */;
buildPhases = (
0CEBDD1F1B39B8C3003A40BB /* Sources */,
0CEBDD201B39B8C3003A40BB /* Frameworks */,
0CEBDD211B39B8C3003A40BB /* Headers */,
0CEBDD221B39B8C3003A40BB /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = PySwiftyRegex;
productName = PySwiftyRegex;
productReference = 0CEBDD241B39B8C3003A40BB /* PySwiftyRegex.framework */;
productType = "com.apple.product-type.framework";
};
0CEBDD2C1B39B8C4003A40BB /* PySwiftyRegexTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 0CEBDD381B39B8C4003A40BB /* Build configuration list for PBXNativeTarget "PySwiftyRegexTests" */;
buildPhases = (
0CEBDD291B39B8C4003A40BB /* Sources */,
0CEBDD2A1B39B8C4003A40BB /* Frameworks */,
0CEBDD2B1B39B8C4003A40BB /* Resources */,
);
buildRules = (
);
dependencies = (
0CEBDD301B39B8C4003A40BB /* PBXTargetDependency */,
);
name = PySwiftyRegexTests;
productName = PySwiftyRegexTests;
productReference = 0CEBDD2D1B39B8C4003A40BB /* PySwiftyRegexTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
0CEBDCD51B39B2FB003A40BB /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0710;
LastUpgradeCheck = 1030;
ORGANIZATIONNAME = "Ce Zheng";
TargetAttributes = {
0CEBDD231B39B8C3003A40BB = {
CreatedOnToolsVersion = 7.0;
LastSwiftMigration = 1030;
};
0CEBDD2C1B39B8C4003A40BB = {
CreatedOnToolsVersion = 7.0;
LastSwiftMigration = 1030;
};
};
};
buildConfigurationList = 0CEBDCD81B39B2FB003A40BB /* Build configuration list for PBXProject "PySwiftyRegex" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 0CEBDCD41B39B2FB003A40BB;
productRefGroup = 0CEBDCDF1B39B2FB003A40BB /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
0CEBDD231B39B8C3003A40BB /* PySwiftyRegex */,
0CEBDD2C1B39B8C4003A40BB /* PySwiftyRegexTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
0CEBDD221B39B8C3003A40BB /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
0CEBDD2B1B39B8C4003A40BB /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
0CEBDD1F1B39B8C3003A40BB /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0CEBDD3E1B39C5EC003A40BB /* PySwiftyRegex.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
0CEBDD291B39B8C4003A40BB /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
795691DB1C74A9B9002B1CA4 /* ReTests.swift in Sources */,
0CEBDD3C1B39C54B003A40BB /* ReRegexObjectTests.swift in Sources */,
0CEBDD3D1B39C54B003A40BB /* ReMatchObjectTests.swift in Sources */,
795691DE1C74AACB002B1CA4 /* TestHelpers.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
0CEBDD301B39B8C4003A40BB /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 0CEBDD231B39B8C3003A40BB /* PySwiftyRegex */;
targetProxy = 0CEBDD2F1B39B8C4003A40BB /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
0CEBDCF01B39B2FC003A40BB /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = PySwiftyRegex/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = me.cezheng.PySwiftyRegex;
PRODUCT_NAME = "$(PROJECT_NAME)";
SUPPORTED_PLATFORMS = "macosx iphoneos appletvos watchos appletvsimulator iphonesimulator watchsimulator";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
TARGETED_DEVICE_FAMILY = "1,2,3,4";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
0CEBDCF11B39B2FC003A40BB /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = PySwiftyRegex/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = me.cezheng.PySwiftyRegex;
PRODUCT_NAME = "$(PROJECT_NAME)";
SUPPORTED_PLATFORMS = "macosx iphoneos appletvos watchos appletvsimulator iphonesimulator watchsimulator";
TARGETED_DEVICE_FAMILY = "1,2,3,4";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
0CEBDD361B39B8C4003A40BB /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_VERSION = A;
GCC_GENERATE_TEST_COVERAGE_FILES = YES;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
MACH_O_TYPE = mh_dylib;
MACOSX_DEPLOYMENT_TARGET = 10.9;
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
0CEBDD371B39B8C4003A40BB /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_VERSION = A;
GCC_GENERATE_TEST_COVERAGE_FILES = YES;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
MACH_O_TYPE = mh_dylib;
MACOSX_DEPLOYMENT_TARGET = 10.9;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 5.0;
};
name = Release;
};
0CEBDD391B39B8C4003A40BB /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = PySwiftyRegexTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.9;
PRODUCT_BUNDLE_IDENTIFIER = "me.cezheng.PySwiftyRegex-OSXTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
0CEBDD3A1B39B8C4003A40BB /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = PySwiftyRegexTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.9;
PRODUCT_BUNDLE_IDENTIFIER = "me.cezheng.PySwiftyRegex-OSXTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 5.0;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
0CEBDCD81B39B2FB003A40BB /* Build configuration list for PBXProject "PySwiftyRegex" */ = {
isa = XCConfigurationList;
buildConfigurations = (
0CEBDCF01B39B2FC003A40BB /* Debug */,
0CEBDCF11B39B2FC003A40BB /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
0CEBDD351B39B8C4003A40BB /* Build configuration list for PBXNativeTarget "PySwiftyRegex" */ = {
isa = XCConfigurationList;
buildConfigurations = (
0CEBDD361B39B8C4003A40BB /* Debug */,
0CEBDD371B39B8C4003A40BB /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
0CEBDD381B39B8C4003A40BB /* Build configuration list for PBXNativeTarget "PySwiftyRegexTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
0CEBDD391B39B8C4003A40BB /* Debug */,
0CEBDD3A1B39B8C4003A40BB /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 0CEBDCD51B39B2FB003A40BB /* Project object */;
}
================================================
FILE: PySwiftyRegex.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:PySwiftyRegex.xcodeproj">
</FileRef>
</Workspace>
================================================
FILE: PySwiftyRegex.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
================================================
FILE: PySwiftyRegex.xcodeproj/xcshareddata/xcschemes/PySwiftyRegex.xcscheme
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1030"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0CEBDD231B39B8C3003A40BB"
BuildableName = "PySwiftyRegex.framework"
BlueprintName = "PySwiftyRegex"
ReferencedContainer = "container:PySwiftyRegex.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "NO"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0CEBDD2C1B39B8C4003A40BB"
BuildableName = "PySwiftyRegexTests.xctest"
BlueprintName = "PySwiftyRegexTests"
ReferencedContainer = "container:PySwiftyRegex.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0CEBDD2C1B39B8C4003A40BB"
BuildableName = "PySwiftyRegexTests.xctest"
BlueprintName = "PySwiftyRegexTests"
ReferencedContainer = "container:PySwiftyRegex.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0CEBDD231B39B8C3003A40BB"
BuildableName = "PySwiftyRegex.framework"
BlueprintName = "PySwiftyRegex"
ReferencedContainer = "container:PySwiftyRegex.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0CEBDD231B39B8C3003A40BB"
BuildableName = "PySwiftyRegex.framework"
BlueprintName = "PySwiftyRegex"
ReferencedContainer = "container:PySwiftyRegex.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0CEBDD231B39B8C3003A40BB"
BuildableName = "PySwiftyRegex.framework"
BlueprintName = "PySwiftyRegex"
ReferencedContainer = "container:PySwiftyRegex.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
================================================
FILE: PySwiftyRegexTests/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
================================================
FILE: PySwiftyRegexTests/ReMatchObjectTests.swift
================================================
// ReMatchObjectTests.swift
// Copyright (c) 2015ー2016 Ce Zheng
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import XCTest
import PySwiftyRegex
class ReMatchObjectTests: XCTestCase {
func testExpand() {
let regex = re.compile("(this).+(that)")
let string = "this one is different from that one."
let m = regex.match(string)
XCTAssertNotNil(m)
let match = m!
XCTAssertEqual(match.string, string)
XCTAssertEqual(match.expand("$2 ~ $1"), "that ~ this")
}
func testGroups() {
let m = re.match("(\\d+)\\.(\\d+)", "24.1632")
XCTAssertNotNil(m)
let match = m!
XCTAssertEqual(match.string, "24.1632")
let groups = match.groups()
XCTAssertFalse(groups.isEmpty)
XCTAssertEqual(groups[0]!, "24")
XCTAssertEqual(groups[1]!, "1632")
}
func testGroupsWithNoGroup() {
let m = re.match("\\d+\\.\\d+", "24.1632")
XCTAssertNotNil(m)
let match = m!
XCTAssertEqual(match.string, "24.1632")
let groups = match.groups()
XCTAssertTrue(groups.isEmpty)
}
func testGroupsWithDefault() {
let m = re.match("(\\d+)\\.?(\\d+)?", "24")
XCTAssertNotNil(m)
let match = m!
let groups = match.groups()
XCTAssertEqual(groups[0]!, "24")
XCTAssertNil(groups[1])
XCTAssertEqual(match.groups("0"), ["24", "0"])
}
}
================================================
FILE: PySwiftyRegexTests/ReRegexObjectTests.swift
================================================
// ReRegexObjectTests.swift
// Copyright (c) 2015ー2016 Ce Zheng
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import XCTest
import PySwiftyRegex
class ReRegexObjectTests: XCTestCase {
func testMatchSuccess() {
let regex = re.compile("(this).+(that)")
let string = "this one is different from that one."
let m = regex.match(string)
XCTAssertNotNil(m)
let match = m!
XCTAssertEqual(match.string, string)
XCTAssertEqual(match.group()!, "this one is different from that")
XCTAssertEqual(match.group(1)!, "this")
XCTAssertEqual(match.group(2)!, "that")
XCTAssertEqual(match.span()!, string.startIndex..<string.index(string.startIndex, offsetBy: 31))
XCTAssertEqual(match.span(1)!, string.startIndex..<string.index(string.startIndex, offsetBy: 4))
XCTAssertEqual(match.span(2)!, string.index(string.startIndex, offsetBy: 27)..<string.index(string.startIndex, offsetBy: 31))
}
func testMatchWithRangeSuccess() {
let regex = re.compile("(this).+(that).*")
let string = "omg this one is different from that one."
let m = regex.match(string, 4, 38)
XCTAssertNotNil(m)
let match = m!
XCTAssertEqual(match.string, string)
XCTAssertEqual(match.group()!, "this one is different from that on")
XCTAssertEqual(match.group(1)!, "this")
XCTAssertEqual(match.group(2)!, "that")
XCTAssertEqual(match.span()!, string.index(string.startIndex, offsetBy: 4)..<string.index(string.startIndex, offsetBy: 38))
XCTAssertEqual(match.span(1)!, string.index(string.startIndex, offsetBy: 4)..<string.index(string.startIndex, offsetBy: 8))
XCTAssertEqual(match.span(2)!, string.index(string.startIndex, offsetBy: 31)..<string.index(string.startIndex, offsetBy: 35))
}
func testMatchFailure() {
let regex = re.compile("(this).+(that)")
let string = " this one is different from that one."
let match = regex.match(string)
XCTAssertNil(match)
}
func testSearchSuccess() {
let regex = re.compile("(this).+(that)")
let string = "this one is different from that one."
let m = regex.search(string)
XCTAssertTrue(m != nil)
let match = m!
XCTAssertEqual(match.string, string)
XCTAssertEqual(match.group()!, "this one is different from that")
XCTAssertEqual(match.group(1)!, "this")
XCTAssertEqual(match.group(2)!, "that")
XCTAssertEqual(match.span()!, string.startIndex..<string.index(string.startIndex, offsetBy: 31))
XCTAssertEqual(match.span(1)!, string.startIndex..<string.index(string.startIndex, offsetBy: 4))
XCTAssertEqual(match.span(2)!, string.index(string.startIndex, offsetBy: 27)..<string.index(string.startIndex, offsetBy: 31))
}
func testSearchWithRangeSuccess() {
let regex = re.compile("(this).+(that) .*")
let string = "omg this one is different from that one."
let m = regex.search(string, 4, 38)
XCTAssertNotNil(m)
let match = m!
XCTAssertEqual(match.string, string)
XCTAssertEqual(match.group()!, "this one is different from that on")
XCTAssertEqual(match.group(1)!, "this")
XCTAssertEqual(match.group(2)!, "that")
XCTAssertEqual(match.span()!, string.index(string.startIndex, offsetBy: 4)..<string.index(string.startIndex, offsetBy: 38))
XCTAssertEqual(match.span(1)!, string.index(string.startIndex, offsetBy: 4)..<string.index(string.startIndex, offsetBy: 8))
XCTAssertEqual(match.span(2)!, string.index(string.startIndex, offsetBy: 31)..<string.index(string.startIndex, offsetBy: 35))
}
func testSearchNestGroupsSuccess() {
let regex = re.compile("((\\s*this\\s*)+).+?((\\s*that\\s*)+)")
let string = "this this this one is different from that that that one."
let m = regex.search(string)
XCTAssertNotNil(m)
let match = m!
XCTAssertEqual(match.string, string)
XCTAssertEqual(match.group()!, "this this this one is different from that that that ")
XCTAssertEqual(match.group(1)!, "this this this ")
XCTAssertEqual(match.group(2)!, "this ")
XCTAssertEqual(match.group(3)!, " that that that ")
XCTAssertEqual(match.group(4)!, "that ")
XCTAssertEqual(match.span()!, string.startIndex..<string.index(string.startIndex, offsetBy: 52))
XCTAssertEqual(match.span(1)!, string.startIndex..<string.index(string.startIndex, offsetBy: 15))
XCTAssertEqual(match.span(2)!, string.index(string.startIndex, offsetBy: 10)..<string.index(string.startIndex, offsetBy: 15))
XCTAssertEqual(match.span(3)!, string.index(string.startIndex, offsetBy: 36)..<string.index(string.startIndex, offsetBy: 52))
XCTAssertEqual(match.span(4)!, string.index(string.startIndex, offsetBy: 47)..<string.index(string.startIndex, offsetBy: 52))
}
func testFindallSuccess() {
let regex = re.compile("([abc]+[123]+)")
let string = "abcd1234-aab113-abc333-adbca3432ddbca332233"
let matches = regex.findall(string)
XCTAssertEqual(matches.count, 4)
XCTAssertEqual(matches, ["aab113", "abc333", "bca3", "bca332233"])
}
func testFindallSuccessWithPos() {
let regex = re.compile("([abc]+[123]+)")
let string = "abcd1234-aab113-abc333-adbca3432ddbca332233"
let matches = regex.findall(string, 21)
XCTAssertEqual(matches.count, 2)
XCTAssertEqual(matches, ["bca3", "bca332233"])
}
func testFindIterSuccess() {
let regex = re.compile("([abc]+[123]+)")
let string = "abcd1234-aab113-abc333-adbca3432ddbca332233"
let matches = regex.finditer(string)
XCTAssertEqual(matches.count, 4)
let expectations = ["aab113", "abc333", "bca3", "bca332233"]
for (index, expectation) in expectations.enumerated() {
let group: String? = matches[index].group()
XCTAssertNotNil(group)
XCTAssertEqual(group!, expectation)
}
}
func testFindIterSuccessWithPos() {
let regex = re.compile("([abc]+[123]+)")
let string = "abcd1234-aab113-abc333-adbca3432ddbca332233"
let matches = regex.finditer(string, 9, 21)
XCTAssertEqual(matches.count, 2)
let expectations = ["aab113", "abc33"]
for (index, expectation) in expectations.enumerated() {
let group: String? = matches[index].group()
XCTAssertNotNil(group)
XCTAssertEqual(group!, expectation)
}
}
func testSplitSuccess() {
let regex = re.compile("[,.]")
let string = "saldkfjalskfd,sdfjlskdfjl.//.sldkfjlskdfj,.sdjflksd."
let substrings = regex.split(string)
XCTAssertEqual(substrings.count, 7)
AssertEqual(substrings, ["saldkfjalskfd", "sdfjlskdfjl", "//", "sldkfjlskdfj", "", "sdjflksd", ""] as [String?])
}
func testSplitWithMaxSplitSuccess() {
let regex = re.compile("[,.]")
let string = "saldkfjalskfd,sdfjlskdfjl.//.sldkfjlskdfj,.sdjflksd."
let substrings = regex.split(string, 5)
XCTAssertEqual(substrings.count, 6)
AssertEqual(substrings, ["saldkfjalskfd", "sdfjlskdfjl", "//", "sldkfjlskdfj", "", "sdjflksd."] as [String?])
}
func testSplitWithGroups() {
let regex = re.compile("([,.])")
let string = "saldkfjalskfd,sdfjlskdfjl.//.sldkfjlskdfj,.sdjflksd."
let substrings = regex.split(string)
XCTAssertEqual(substrings.count, 13)
AssertEqual(substrings, ["saldkfjalskfd", ",", "sdfjlskdfjl", ".", "//", ".", "sldkfjlskdfj", ",", "", ".", "sdjflksd", ".", ""] as [String?])
}
func testSubSuccess() {
let regex = re.compile("[sS]oviet")
let string = "Soviet will surely win the war, let's cheer for the great soviet"
let subbed = regex.sub("Allies", string)
XCTAssertEqual(subbed, "Allies will surely win the war, let's cheer for the great Allies")
}
func testSubNoOccurrence() {
let regex = re.compile("[sS]oviet")
let string = "Allies will surely win the war, let's cheer for the great Allies"
let subbed = regex.sub("Allies", string)
XCTAssertEqual(subbed, string)
}
func testSubWithCount() {
let regex = re.compile("[sS]oviet")
let string = "Soviet will surely win the war, let's cheer for the great soviet"
XCTAssertEqual(regex.sub("Allies", string, 1), "Allies will surely win the war, let's cheer for the great soviet")
XCTAssertEqual(regex.sub("Allies", string, 2), "Allies will surely win the war, let's cheer for the great Allies")
XCTAssertEqual(regex.sub("Allies", string, -1), string)
}
func testSubWithCaptureGroups() {
let regex = re.compile("(Soviet)(.*)(Allies)")
let string = "Soviet will beat Allies"
XCTAssertEqual(regex.sub("$3$2$1", string), "Allies will beat Soviet")
}
func testCompileInvalidPattern() {
let regex = re.compile("(")
XCTAssertFalse(regex.isValid)
XCTAssertNil(regex.search("test"))
XCTAssertNil(regex.match("test"))
XCTAssertNil(regex.nsRegex)
AssertEqual(regex.split("sdf(sdf"), [])
XCTAssertEqual(regex.sub("o", "hahaha("), "hahaha(")
XCTAssertEqual(regex.subn("o", "hahaha(").1, 0)
}
}
================================================
FILE: PySwiftyRegexTests/ReTests.swift
================================================
// ReTests.swift
// Copyright (c) 2015ー2016 Ce Zheng
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import XCTest
import PySwiftyRegex
class ReTests: XCTestCase {
func testCompileValidRegex() {
let regex = re.compile("(\\W+)", flags: [.allowCommentsAndWhitespace, .anchorsMatchLines])
XCTAssertTrue(regex.isValid)
XCTAssertEqual(regex.flags, NSRegularExpression.Options.allowCommentsAndWhitespace.union(.anchorsMatchLines))
XCTAssertEqual(regex.pattern, "(\\W+)")
XCTAssertEqual(regex.nsRegex!, try! NSRegularExpression(pattern: "(\\W+)", options: NSRegularExpression.Options.allowCommentsAndWhitespace.union(.anchorsMatchLines)))
XCTAssertEqual(regex.groups, 1)
}
func testCompileInvalidRegex() {
let regex = re.compile("(\\W+", flags: [.allowCommentsAndWhitespace, .anchorsMatchLines])
XCTAssertFalse(regex.isValid)
XCTAssertEqual(regex.flags, NSRegularExpression.Options(rawValue: 0))
XCTAssertEqual(regex.pattern, "(\\W+")
XCTAssertNil(regex.nsRegex)
XCTAssertEqual(regex.groups, 0)
}
func testSearch() {
AssertEqual(re.search("a", "ssa")!.groups(), [])
AssertEqual(re.search("(a)", "ssa")!.groups(), ["a"])
XCTAssertEqual(re.search("(a)", "ssa")!.group(0), "a")
XCTAssertEqual(re.search("(a)", "ssa")!.group(1), "a")
AssertEqual(re.search("(a)", "ssa")!.group([1, 1]), ["a", "a"])
}
func testMatch() {
AssertEqual(re.match("a", "a")!.groups(), [])
AssertEqual(re.match("(a)", "a")!.groups(), ["a"])
XCTAssertEqual(re.match("(a)", "a")!.group(0), "a")
XCTAssertEqual(re.match("(a)", "a")!.group(1), "a")
AssertEqual(re.match("(a)", "a")!.group([1, 1]), ["a", "a"])
}
func testSplit() {
AssertEqual(re.split(":", ":a:b::c"), ["", "a", "b", "", "c"])
AssertEqual(re.split(":*", ":a:b::c").map {$0!}, ["", "a", "b", "c"])
AssertEqual(re.split("(:*)", ":a:b::c"), ["", ":", "a", ":", "b", "::", "c"])
AssertEqual(re.split("(?::*)", ":a:b::c"), ["", "a", "b", "c"])
AssertEqual(re.split("(:)*", ":a:b::c"), ["", ":", "a", ":", "b", ":", "c"])
AssertEqual(re.split("([b:]+)", ":a:b::c"), ["", ":", "a", ":b::", "c"])
AssertEqual(re.split("(b)|(:+)", ":a:b::c"), ["", nil, ":", "a", nil, ":", "", "b", nil, "", nil, "::", "c"])
AssertEqual(re.split("(?:b)|(?::+)", ":a:b::c"), ["", "a", "", "", "c"])
}
func testFindAll() {
XCTAssertEqual(re.findall(":+", "abc"), [])
XCTAssertEqual(re.findall(":+", "a:b::c:::d"), [":", "::", ":::"])
XCTAssertEqual(re.findall("(:+)", "a:b::c:::d"), [":", "::", ":::"])
XCTAssertEqual(re.findall("(:)(:*)", "a:b::c:::d"), [":", "::", ":::"])
}
func testFindIter() {
let m = re.finditer(":+", "a:b::c:::d")
XCTAssertEqual(m.map {$0.group(0)!}, [":", "::", ":::"])
}
func testSub() {
XCTAssertEqual(re.sub("(?i)b+", "x", "bbbb BBBB"), "x x")
XCTAssertEqual(re.sub("x", "\\\\N{LATIN CAPITAL LETTER A}",
"x"), "\\N{LATIN CAPITAL LETTER A}")
XCTAssertEqual(re.sub(".", "\n", "x"), "\n")
}
func testSubN() {
AssertEqual(re.subn("(?i)b+", "x", "bbbb BBBB"), ("x x", 2))
AssertEqual(re.subn("b+", "x", "bbbb BBBB"), ("x BBBB", 1))
AssertEqual(re.subn("b+", "x", "xyz"), ("xyz", 0))
AssertEqual(re.subn("b*", "x", "xyz"), ("xxxyxzx", 4))
AssertEqual(re.subn("b*", "x", "xyz", 2), ("xxxyz", 2))
}
}
================================================
FILE: PySwiftyRegexTests/TestHelpers.swift
================================================
// ReRegexObjectTests.swift
// Copyright (c) 2016 Ce Zheng
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import XCTest
func AssertEqual<T1: Equatable, T2: Equatable> (_ left: (T1, T2), _ right: (T1, T2)) {
XCTAssertTrue((left.0 == right.0) && (left.1 == right.1))
}
func AssertEqual<T: Equatable>(_ left: [T?], _ right: [T?]) {
XCTAssertEqual(left.count, right.count)
for (index, item) in left.enumerated() {
XCTAssertEqual(item, right[index])
}
}
================================================
FILE: README-ja.md
================================================
# PySwiftyRegex
[](https://cocoapods.org/pods/PySwiftyRegex)
[](http://opensource.org/licenses/MIT)
[](https://github.com/Carthage/Carthage)
[](http://cocoadocs.org/docsets/PySwiftyRegex)
[](http://twitter.com/AdamoCheng)
Pythonのようなスッキリした正規表現ライブラリー。
[English](README.md)
[简体中文](README-zh.md)
[한국어](README-ko.md)
## コードをみましょう
```swift
import PySwiftyRegex
if let m = re.search("[Tt]his is (.*?)easy", "I think this is really easy!!!") {
m.group() // "this is really easy"
m.group(1) // "really "
}
```
よく使われるメッソドの用例は[こちら](#more_usage)。
## 環境
- iOS 7.0+ / Mac OS X 10.9+
- Xcode 8.0+
> Swift 2.3はバージョン[0.3.0](../../releases/tag/0.3.0)をご利用ください。
## インストール
> **Embedded frameworks を使うには iOS 8 または OS X Mavericks 以上は必要です**
>
> Deployment Target は iOS 7 のプロジェクトで `PySwiftyRegex` を使うには, [PySwiftyRegex.swift](PySwiftyRegex/PySwiftyRegex.swift) のソースファイルをダウンロードして、Xcodeプロジェクトに追加するのは必要となります。
### CocoaPods(iOS 8+, OS X 10.9+)
[Cocoapods](http://cocoapods.org/) で簡単に `PySwiftyRegex` をインストールできます。 下記のように`Podfile`を編集してください:
```ruby
platform :ios, '8.0'
use_frameworks!
target 'MyApp' do
pod 'PySwiftyRegex', '~> 1.0.0'
end
```
そして、下記のコマンドを実行してください:
```bash
$ pod install
```
### Carthage(iOS 8+, OS X 10.9+)
下記の行を `Cartfile` か `Cartfile.private` かに追加してください:
```
github "cezheng/PySwiftyRegex" ~> 1.0.0
```
そして、下記のコマンドを実行してください:
```
$ carthage update
```
最後に、ビルドターゲットの`General` -> `Embedded Binaries`に、Carthageがビルドした`PySwiftyRegex.framework`を追加してください。
## 対応したreメソッド
[**re**](https://docs.python.org/2/library/re.html) モデルを使ったことがあれば, すぐこのライブラリーをご利用できると思います。もしなかったら、下記のPythonドキュメントのリンクをご覧いただけると、このシンプルなモデルに一目惚れするかもしれませんw
### [re](https://docs.python.org/2/library/re.html#module-contents)
* [re.compile](https://docs.python.org/2/library/re.html#re.compile)
* [re.search](https://docs.python.org/2/library/re.html#re.search)
* [re.match](https://docs.python.org/2/library/re.html#re.match)
* [re.split](https://docs.python.org/2/library/re.html#re.split)
* [re.findall](https://docs.python.org/2/library/re.html#re.findall)
* [re.finditer](https://docs.python.org/2/library/re.html#re.finditer)
* [re.sub](https://docs.python.org/2/library/re.html#re.sub)
* [re.subn](https://docs.python.org/2/library/re.html#re.subn)
### [re.RegexObject](https://docs.python.org/2/library/re.html#regular-expression-objects)
* [search](https://docs.python.org/2/library/re.html#re.RegexObject.search)
* [match](https://docs.python.org/2/library/re.html#re.RegexObject.match)
* [split](https://docs.python.org/2/library/re.html#re.RegexObject.split)
* [findall](https://docs.python.org/2/library/re.html#re.RegexObject.findall)
* [finditer](https://docs.python.org/2/library/re.html#re.RegexObject.finditer)
* [sub](https://docs.python.org/2/library/re.html#re.RegexObject.sub)
* [subn](https://docs.python.org/2/library/re.html#re.RegexObject.subn)
### [re.MatchObject](https://docs.python.org/2/library/re.html#match-objects)
* [expand](https://docs.python.org/2/library/re.html#re.MatchObject.expand)
* [group](https://docs.python.org/2/library/re.html#re.MatchObject.group)
* [groups](https://docs.python.org/2/library/re.html#re.MatchObject.groups)
* [span](https://docs.python.org/2/library/re.html#re.MatchObject.span)
## <a name="more_usage"></a>よく使われるメッソドの用例
### RegexObjectをコンパイルする
```swift
let regex = re.compile("this(.+)that")
```
### 文字列の始めからマッチングする
```swift
if let m = regex.match("this one is different from that") {
m.group() //"this one is different from that"
m.group(1) //" one is different from "
}
```
### 文字列の中にパターンを探す (first match)
```swift
if let m = regex.search("I want this one, not that one") {
m.group() //"this one, not that one"
m.group(1) //" one, not "
}
```
### マッチングできた全ての文字列を取得する
```swift
regex.findall("this or that, this and that") // ["this or that", "this and that"]
```
### マッチングできた全てのMatchObjectを取得する
```swift
for m in regex.finditer("this or that, this and that") {
m.group() // 1st time: "this or that", second time: "this and that"
m.group(1) // 1st time: " or ", second time: " and "
}
```
### パターンで文字列を分割する
```swift
let regex = re.compile("[\\+\\-\\*/]")
// デフォルト、全て分割する
regex.split("1+2-3*4/5") // ["1", "2", "3", "4", "5"]
// 最大分割回数 = 2
regex.split("1+2-3*4/5", 2) // ["1", "2", "3*4/5"]
```
### パターンで文字列を置換する
```swift
let regex = re.compile("[Yy]ou")
// 全て置換する (この例は2回)
regex.sub("u", "You guys go grap your food") // "u guys go grap ur food"
regex.subn("u", "You guys go grap your food") // ("u guys go grap ur food", 2)
// 最大置換回数を1回にする (この例は1回)
regex.sub("u", "You guys go grap your food", 1) // "u guys go grap your food"
regex.subn("u", "You guys go grap your food", 1) // ("u guys go grap your food", 1)
```
## ライセンス
`PySwiftyRegex` のオープンソースライセンスは MIT です。 詳しくはこちら [LICENSE](LICENSE) 。
================================================
FILE: README-ko.md
================================================
# PySwiftyRegex
[](https://cocoapods.org/pods/PySwiftyRegex)
[](http://opensource.org/licenses/MIT)
[](https://github.com/Carthage/Carthage)
[](http://cocoadocs.org/docsets/PySwiftyRegex)
[](http://twitter.com/AdamoCheng)
Swift에서 정규표현식을 Python처럼 쉽게 다뤄보세요.
[English](README.md)
[简体中文](README-zh.md)
[日本語](README-ja.md)
## 굉장히 쉽습니다
```swift
import PySwiftyRegex
if let m = re.search("[Tt]his is (.*?)easy", "I think this is really easy!!!") {
m.group() // "this is really easy"
m.group(1) // "really "
}
```
아래에서 [더 많은 예제](#more_usage)를 볼 수 있습니다.
## 요구사항
- iOS 7.0+ / Mac OS X 10.9+
- Xcode 8.0+
> Swift 2.3의 경우 버전 [0.3.0](../../releases/tag/0.3.0)를 이용해주십시오.
## 설치하기
> **임베드된 프레임워크를 사용하려면 iOS 8 또는 OS X Mavericks 이상을 지원해야 합니다.**
>
> `PySwiftyRegex`을 iOS 7 타겟 프로젝트에서 사용하려면 [CocoaSeeds](#cocoaseeds-for-ios7)를 사용하거나 혹은 [PySwiftyRegex.swift](PySwiftyRegex/PySwiftyRegex.swift) 파일을 다운받아 프로젝트에 직접 포함시켜야 합니다.
### CocoaPods (iOS 8+, OS X 10.9+)
[CocoaPods](http://cocoapods.org/)를 사용해서 `PySwiftyRegex`를 쉽게 설치할 수 있습니다. 다음과 같은 내용의 **Podfile**을 만들어주세요.
```ruby
platform :ios, '8.0'
use_frameworks!
target 'MyApp' do
pod 'PySwiftyRegex', '~> 1.0.0'
end
```
그리고 쉘에서 아래 명령어를 실행하면 설치됩니다.
```bash
$ pod install
```
### Carthage (iOS 8+, OS X 10.9+)
**Cartfile** 또는 **Cartfile.private**에 아래 라인을 추가합니다.
```
github "cezheng/PySwiftyRegex" ~> 1.0.0
```
그리고 쉘에서 다음 명령어를 실행합니다.
```
$ carthage update
```
Carthage가 생성한 **PySwiftyRegex.framework**를 Xcode 프로젝트의 'General' 설정 아래의 'Embedded Binaries'에 추가합니다.
### CocoaSeeds (iOS 7+)
[CocoaSeeds](https://github.com/devxoul/CocoaSeeds)를 사용하면 Swift로 작성된 라이브러리를 iOS 7 프로젝트에서 사용할 수 있습니다.
먼저, **Seedfile**을 생성합니다.
```ruby
target :MyApp do
github 'cezheng/PySwiftyRegex', '1.0.0', :files => 'PySwiftyRegex/PySwiftyRegex.swift'
end
```
그리고 다음과 같은 쉘 명령어를 실행합니다.
```console
$ seed install
```
PySwiftyRegex.swift 파일이 Xcode 프로젝트에 자동으로 포함된 것을 볼 수 있습니다. 즐코딩!
## 사용 가능한 re 모듈
Python의 [**re**](https://docs.python.org/2/library/re.html) 모듈에 익숙하다면 사용하는데 어려움이 없을 것입니다. 처음이거나 익숙하지 않은 경우, 아래 항목들을 보고 Python에서 정규표현식을 다루는 방식이 `NSRegularExpression`보다 어떻게 더 좋은지 확인해보세요.
### [re](https://docs.python.org/2/library/re.html#module-contents)
* [re.compile](https://docs.python.org/2/library/re.html#re.compile)
* [re.search](https://docs.python.org/2/library/re.html#re.search)
* [re.match](https://docs.python.org/2/library/re.html#re.match)
* [re.split](https://docs.python.org/2/library/re.html#re.split)
* [re.findall](https://docs.python.org/2/library/re.html#re.findall)
* [re.finditer](https://docs.python.org/2/library/re.html#re.finditer)
* [re.sub](https://docs.python.org/2/library/re.html#re.sub)
* [re.subn](https://docs.python.org/2/library/re.html#re.subn)
### [re.RegexObject](https://docs.python.org/2/library/re.html#regular-expression-objects)
* [search](https://docs.python.org/2/library/re.html#re.RegexObject.search)
* [match](https://docs.python.org/2/library/re.html#re.RegexObject.match)
* [split](https://docs.python.org/2/library/re.html#re.RegexObject.split)
* [findall](https://docs.python.org/2/library/re.html#re.RegexObject.findall)
* [finditer](https://docs.python.org/2/library/re.html#re.RegexObject.finditer)
* [sub](https://docs.python.org/2/library/re.html#re.RegexObject.sub)
* [subn](https://docs.python.org/2/library/re.html#re.RegexObject.subn)
### [re.MatchObject](https://docs.python.org/2/library/re.html#match-objects)
* [expand](https://docs.python.org/2/library/re.html#re.MatchObject.expand)
* [group](https://docs.python.org/2/library/re.html#re.MatchObject.group)
* [groups](https://docs.python.org/2/library/re.html#re.MatchObject.groups)
* [span](https://docs.python.org/2/library/re.html#re.MatchObject.span)
## <a name="more_usage"></a>더 많은 예제
### 재사용을 위해 RegexObject 객체 컴파일하기
```swift
let regex = re.compile("this(.+)that")
```
### 문자열 첫 부분부터 패턴 매칭하기
```swift
if let m = regex.match("this one is different from that") {
m.group() //"this one is different from that"
m.group(1) //" one is different from "
}
```
### 패턴 검색하기 (가장 먼저 매칭되는 패턴)
```swift
if let m = regex.search("I want this one, not that one") {
m.group() //"this one, not that one"
m.group(1) //" one, not "
}
```
### 매칭되는 모든 패턴 검색하기
```swift
regex.findall("this or that, this and that") // ["this or that", "this and that"]
```
### 모든 매칭 결과 가져오기
```swift
for m in regex.finditer("this or that, this and that") {
m.group() // 1st time: "this or that", 2nd time: "this and that"
m.group(1) // 1st time: " or ", 2nd time: " and "
}
```
### 정규식으로 문자열 자르기
```swift
let regex = re.compile("[\\+\\-\\*/]")
// By default, will split at all occurrences of the pattern
regex.split("1+2-3*4/5") // ["1", "2", "3", "4", "5"]
// Setting a maxsplit = 2
regex.split("1+2-3*4/5", 2) // ["1", "2", "3*4/5"]
```
### 패턴 치환하기
```swift
let regex = re.compile("[Yy]ou")
// Replacing all occurrences (2 times in this example)
regex.sub("u", "You guys go grap your food") // "u guys go grap ur food"
regex.subn("u", "You guys go grap your food") // ("u guys go grap ur food", 2)
// Setting maximum replace count = 1 (1 times in this example)
regex.sub("u", "You guys go grap your food", 1) // "u guys go grap your food"
regex.subn("u", "You guys go grap your food", 1) // ("u guys go grap your food", 1)
```
## 라이센스
`PySwiftyRegex`는 MIT 라이센스 하에 배포됩니다. 자세한 내용은 [LICENSE](LICENSE) 파일을 참고하세요.
================================================
FILE: README-zh.md
================================================
# PySwiftyRegex
[](https://cocoapods.org/pods/PySwiftyRegex)
[](http://opensource.org/licenses/MIT)
[](https://github.com/Carthage/Carthage)
[](http://cocoadocs.org/docsets/PySwiftyRegex)
[](http://twitter.com/AdamoCheng)
像Python一样简洁高效地作正则处理。
[English](README.md)
[日本語](README-ja.md)
[한국어](README-ko.md)
## 先上代码
```swift
import PySwiftyRegex
if let m = re.search("[Tt]his is (.*?)easy", "I think this is really easy!!!") {
m.group() // "this is really easy"
m.group(1) // "really "
}
```
查看 [常见用例](#more_usage).
## 环境
- iOS 7.0+ / Mac OS X 10.9+
- Xcode 8.0+
> Swift 2.3请使用[0.3.0](../../releases/tag/0.3.0)版。
## 导入
> **使用 Embedded frameworks 至少需要 iOS 8 或 OS X Mavericks.**
>
> 如果您的项目需要支持iOS 7但仍想使用 `PySwiftyRegex`, 您需要将源代码文件 [PySwiftyRegex.swift](https://github.com/cezheng/PySwiftyRegex/blob/master/PySwiftyRegex/PySwiftyRegex.swift) 下载并添加到您的Xcode项目中。
### CocoaPods(iOS 8+, OS X 10.9+)
您可以通过 [Cocoapods](http://cocoapods.org/) 来将 `PySwiftyRegex` 添加到您的项目中。 下面是一个示例的`Podfile`:
```ruby
platform :ios, '8.0'
use_frameworks!
target 'MyApp' do
pod 'PySwiftyRegex', '~> 0.2.0'
end
```
配置好Podfile后执行如下命令:
```bash
$ pod install
```
### Carthage(iOS 8+, OS X 10.9+)
往 `Cartfile` 或 `Cartfile.private` 中加入如下一行:
```
github "cezheng/PySwiftyRegex" ~> 0.2.0
```
然后执行如下命令:
```
$ carthage update
```
最后将Carthage编译出来的`PySwiftyRegex.framework`拖拽入目标的`General` -> `Embedded Binaries`。
## 已实现的re模块方法
如果您已有 [**re**](https://docs.python.org/2/library/re.html) 模块的使用经验, 那么基本上将这个库导入到项目中就可以直接开始用了。 如果没有,或许可以点击下方的链接传送到Python的文档页面大致了解一下为何re模块会比NSRegualarExpression的API更加好用。
### [re](https://docs.python.org/2/library/re.html#module-contents)
* [re.compile](https://docs.python.org/2/library/re.html#re.compile)
* [re.search](https://docs.python.org/2/library/re.html#re.search)
* [re.match](https://docs.python.org/2/library/re.html#re.match)
* [re.split](https://docs.python.org/2/library/re.html#re.split)
* [re.findall](https://docs.python.org/2/library/re.html#re.findall)
* [re.finditer](https://docs.python.org/2/library/re.html#re.finditer)
* [re.sub](https://docs.python.org/2/library/re.html#re.sub)
* [re.subn](https://docs.python.org/2/library/re.html#re.subn)
### [re.RegexObject](https://docs.python.org/2/library/re.html#regular-expression-objects)
* [search](https://docs.python.org/2/library/re.html#re.RegexObject.search)
* [match](https://docs.python.org/2/library/re.html#re.RegexObject.match)
* [split](https://docs.python.org/2/library/re.html#re.RegexObject.split)
* [findall](https://docs.python.org/2/library/re.html#re.RegexObject.findall)
* [finditer](https://docs.python.org/2/library/re.html#re.RegexObject.finditer)
* [sub](https://docs.python.org/2/library/re.html#re.RegexObject.sub)
* [subn](https://docs.python.org/2/library/re.html#re.RegexObject.subn)
### [re.MatchObject](https://docs.python.org/2/library/re.html#match-objects)
* [expand](https://docs.python.org/2/library/re.html#re.MatchObject.expand)
* [group](https://docs.python.org/2/library/re.html#re.MatchObject.group)
* [groups](https://docs.python.org/2/library/re.html#re.MatchObject.groups)
* [span](https://docs.python.org/2/library/re.html#re.MatchObject.span)
## <a name="more_usage"></a>常用方法用例
### 创建可重复使用的正则表达式对象
```swift
let regex = re.compile("this(.+)that")
```
### 从字符串起始点开始匹配
```swift
if let m = regex.match("this one is different from that") {
m.group() //"this one is different from that"
m.group(1) //" one is different from "
}
```
### 在字符串中搜索第一个匹配
```swift
if let m = regex.search("I want this one, not that one") {
m.group() //"this one, not that one"
m.group(1) //" one, not "
}
```
### 查找所有匹配字串
```swift
regex.findall("this or that, this and that") // ["this or that", "this and that"]
```
### 获得所有匹配字串的匹配结果
```swift
for m in regex.finditer("this or that, this and that") {
m.group() // 第1次: "this or that", 第2次: "this and that"
m.group(1) // 第1次: " or ", 第2次: " and "
}
```
### 用正则表达式分割字符串
```swift
let regex = re.compile("[\\+\\-\\*/]")
// 默认将做最多次分割
regex.split("1+2-3*4/5") // ["1", "2", "3", "4", "5"]
// 设定最大分割次数为2
regex.split("1+2-3*4/5", 2) // ["1", "2", "3*4/5"]
```
### 正则替换
```swift
let regex = re.compile("[Yy]ou")
// 替换所有匹配 (本例中替换了2次)
regex.sub("u", "You guys go grap your food") // "u guys go grap ur food"
regex.subn("u", "You guys go grap your food") // ("u guys go grap ur food", 2)
// 设定最大替换次数 (本例中替换了1次)
regex.sub("u", "You guys go grap your food", 1) // "u guys go grap your food"
regex.subn("u", "You guys go grap your food", 1) // ("u guys go grap your food", 1)
```
## 开源协议
`PySwiftyRegex` 使用MIT许可协议。 详见 [LICENSE](https://github.com/cezheng/PySwiftyRegex/blob/master/LICENSE) 。
================================================
FILE: README.md
================================================
# PySwiftyRegex
[](https://cocoapods.org/pods/PySwiftyRegex)
[](http://opensource.org/licenses/MIT)
[](https://github.com/Carthage/Carthage)
[](http://cocoadocs.org/docsets/PySwiftyRegex)
[](http://twitter.com/AdamoCheng)
Easily deal with Regex in Swift in a Pythonic way.
[简体中文](README-zh.md)
[日本語](README-ja.md)
[한국어](README-ko.md)
## This is Easy
```swift
import PySwiftyRegex
if let m = re.search("[Tt]his is (.*?)easy", "I think this is really easy!!!") {
m.group() // "this is really easy"
m.group(1) // "really "
}
```
See [More examples](#more_usage).
## Requirements
- iOS 7.0+ / Mac OS X 10.9+
- Xcode 8.0+
< For Swift 2.3 please use version [0.3.0](../../releases/tag/0.3.0).
## Installation
> **Embedded frameworks require a minimum deployment target of iOS 8 or OS X Mavericks.**
>
> To use `PySwiftyRegex` with a project targeting iOS 7, consider using [CocoaSeeds](#cocoaseeds-for-ios7) or copy the [PySwiftyRegex.swift](PySwiftyRegex/PySwiftyRegex.swift) file into your project.
### CocoaPods(iOS 8+, OS X 10.9+)
You can use [Cocoapods](http://cocoapods.org/) to install `PySwiftyRegex` by adding it to your to your `Podfile`:
```ruby
platform :ios, '8.0'
use_frameworks!
target 'MyApp' do
pod 'PySwiftyRegex', '~> 1.0.0'
end
```
Then, run the following command:
```bash
$ pod install
```
### Carthage(iOS 8+, OS X 10.9+)
Adding the following line to your `Cartfile` or `Cartfile.private`:
```
github "cezheng/PySwiftyRegex" ~> 1.0.0
```
Run the following command:
```
$ carthage update
```
Then drag the `PySwiftyRegex.framework` built by Carthage into your target's `General` -> `Embedded Binaries`.
### CocoaSeeds (for iOS 7)
[CocoaSeeds](https://github.com/devxoul/CocoaSeeds) allows you to use Swift libraries in iOS 7 projects.
Create **Seedfile**:
```ruby
target :MyApp do
github 'cezheng/PySwiftyRegex', '1.0.0', :files => 'PySwiftyRegex/PySwiftyRegex.swift'
end
```
Then run the following command:
```console
$ seed install
```
Now you can see the PySwiftyRegex.swift file in your Xcode project. Build and enjoy!
## Supported re methods
If you are familiar with Python's [**re**](https://docs.python.org/2/library/re.html) module, you are ready to go. If not, you may like to check how Python's re is better than the cumbersome NSRegularExpression's APIs, by clicking at the items below.
### [re](https://docs.python.org/2/library/re.html#module-contents)
* [re.compile](https://docs.python.org/2/library/re.html#re.compile)
* [re.search](https://docs.python.org/2/library/re.html#re.search)
* [re.match](https://docs.python.org/2/library/re.html#re.match)
* [re.split](https://docs.python.org/2/library/re.html#re.split)
* [re.findall](https://docs.python.org/2/library/re.html#re.findall)
* [re.finditer](https://docs.python.org/2/library/re.html#re.finditer)
* [re.sub](https://docs.python.org/2/library/re.html#re.sub)
* [re.subn](https://docs.python.org/2/library/re.html#re.subn)
### [re.RegexObject](https://docs.python.org/2/library/re.html#regular-expression-objects)
* [search](https://docs.python.org/2/library/re.html#re.RegexObject.search)
* [match](https://docs.python.org/2/library/re.html#re.RegexObject.match)
* [split](https://docs.python.org/2/library/re.html#re.RegexObject.split)
* [findall](https://docs.python.org/2/library/re.html#re.RegexObject.findall)
* [finditer](https://docs.python.org/2/library/re.html#re.RegexObject.finditer)
* [sub](https://docs.python.org/2/library/re.html#re.RegexObject.sub)
* [subn](https://docs.python.org/2/library/re.html#re.RegexObject.subn)
### [re.MatchObject](https://docs.python.org/2/library/re.html#match-objects)
* [expand](https://docs.python.org/2/library/re.html#re.MatchObject.expand)
* [group](https://docs.python.org/2/library/re.html#re.MatchObject.group)
* [groups](https://docs.python.org/2/library/re.html#re.MatchObject.groups)
* [span](https://docs.python.org/2/library/re.html#re.MatchObject.span)
## <a name="more_usage"></a>More Usage Examples
### Compile a RegexObject for future reuse
```swift
let regex = re.compile("this(.+)that")
```
### Matching a pattern from beginning
```swift
if let m = regex.match("this one is different from that") {
m.group() //"this one is different from that"
m.group(1) //" one is different from "
}
```
### Searching a pattern (first match)
```swift
if let m = regex.search("I want this one, not that one") {
m.group() //"this one, not that one"
m.group(1) //" one, not "
}
```
### Find all occurrences of a pattern
```swift
regex.findall("this or that, this and that") // ["this or that", "this and that"]
```
### Get match results for all occurrences of a pattern
```swift
for m in regex.finditer("this or that, this and that") {
m.group() // 1st time: "this or that", 2nd time: "this and that"
m.group(1) // 1st time: " or ", 2nd time: " and "
}
```
### Splitting a string with pattern
```swift
let regex = re.compile("[\\+\\-\\*/]")
// By default, will split at all occurrences of the pattern
regex.split("1+2-3*4/5") // ["1", "2", "3", "4", "5"]
// Setting a maxsplit = 2
regex.split("1+2-3*4/5", 2) // ["1", "2", "3*4/5"]
```
### Replacing a pattern
```swift
let regex = re.compile("[Yy]ou")
// Replacing all occurrences (2 times in this example)
regex.sub("u", "You guys go grap your food") // "u guys go grap ur food"
regex.subn("u", "You guys go grap your food") // ("u guys go grap ur food", 2)
// Setting maximum replace count = 1 (1 times in this example)
regex.sub("u", "You guys go grap your food", 1) // "u guys go grap your food"
regex.subn("u", "You guys go grap your food", 1) // ("u guys go grap your food", 1)
```
## License
`PySwiftyRegex` is released under the MIT license. See [LICENSE](LICENSE) for details.
gitextract_eolrdn6l/ ├── .gitignore ├── .swift-version ├── .travis.yml ├── LICENSE ├── PySwiftyRegex/ │ ├── Info.plist │ ├── PySwiftyRegex.h │ └── PySwiftyRegex.swift ├── PySwiftyRegex.podspec ├── PySwiftyRegex.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata/ │ └── xcschemes/ │ └── PySwiftyRegex.xcscheme ├── PySwiftyRegexTests/ │ ├── Info.plist │ ├── ReMatchObjectTests.swift │ ├── ReRegexObjectTests.swift │ ├── ReTests.swift │ └── TestHelpers.swift ├── README-ja.md ├── README-ko.md ├── README-zh.md └── README.md
Condensed preview — 21 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (100K chars).
[
{
"path": ".gitignore",
"chars": 854,
"preview": "# Xcode\n#\n# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore\n\n"
},
{
"path": ".swift-version",
"chars": 4,
"preview": "4.0\n"
},
{
"path": ".travis.yml",
"chars": 633,
"preview": "language: objective-c\n\nos: osx\nosx_image: xcode10.3\n\nenv:\n global:\n - XCODEPROJ=\"PySwiftyRegex.xcodeproj\"\n - SCHE"
},
{
"path": "LICENSE",
"chars": 1051,
"preview": "Copyright (c) 2015 Ce Zheng\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this softwa"
},
{
"path": "PySwiftyRegex/Info.plist",
"chars": 914,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "PySwiftyRegex/PySwiftyRegex.h",
"chars": 1522,
"preview": "// PySwiftyRegex.h\n// Copyright (c) 2015ー2016 Ce Zheng\n//\n// Permission is hereby granted, free of charge, to any person"
},
{
"path": "PySwiftyRegex/PySwiftyRegex.swift",
"chars": 21853,
"preview": "// PySwiftyRegex.swift\n// Copyright (c) 2015ー2016 Ce Zheng\n//\n// Permission is hereby granted, free of charge, to any pe"
},
{
"path": "PySwiftyRegex.podspec",
"chars": 681,
"preview": "Pod::Spec.new do |s|\n s.name = \"PySwiftyRegex\"\n s.version = \"3.0.0\"\n s.license = \"MIT\"\n s.summary "
},
{
"path": "PySwiftyRegex.xcodeproj/project.pbxproj",
"chars": 17880,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "PySwiftyRegex.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 158,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:PySwiftyRegex.x"
},
{
"path": "PySwiftyRegex.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "PySwiftyRegex.xcodeproj/xcshareddata/xcschemes/PySwiftyRegex.xcscheme",
"chars": 4334,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"1030\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "PySwiftyRegexTests/Info.plist",
"chars": 733,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "PySwiftyRegexTests/ReMatchObjectTests.swift",
"chars": 2338,
"preview": "// ReMatchObjectTests.swift\n// Copyright (c) 2015ー2016 Ce Zheng\n//\n// Permission is hereby granted, free of charge, to a"
},
{
"path": "PySwiftyRegexTests/ReRegexObjectTests.swift",
"chars": 9869,
"preview": "// ReRegexObjectTests.swift\n// Copyright (c) 2015ー2016 Ce Zheng\n//\n// Permission is hereby granted, free of charge, to a"
},
{
"path": "PySwiftyRegexTests/ReTests.swift",
"chars": 4378,
"preview": "// ReTests.swift\n// Copyright (c) 2015ー2016 Ce Zheng\n//\n// Permission is hereby granted, free of charge, to any person o"
},
{
"path": "PySwiftyRegexTests/TestHelpers.swift",
"chars": 1492,
"preview": "// ReRegexObjectTests.swift\n// Copyright (c) 2016 Ce Zheng\n//\n// Permission is hereby granted, free of charge, to any pe"
},
{
"path": "README-ja.md",
"chars": 5172,
"preview": "# PySwiftyRegex\n[](https://cocoapods.org/po"
},
{
"path": "README-ko.md",
"chars": 5762,
"preview": "# PySwiftyRegex\n[](https://cocoapods.org/po"
},
{
"path": "README-zh.md",
"chars": 5054,
"preview": "# PySwiftyRegex\n[](https://cocoapods.org/po"
},
{
"path": "README.md",
"chars": 6146,
"preview": "# PySwiftyRegex\n[](https://cocoapods.org/po"
}
]
About this extraction
This page contains the full source code of the cezheng/PySwiftyRegex GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 21 files (88.9 KB), approximately 26.8k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.