From 61ef7f258f01132108d914202c58154b48a46d2e Mon Sep 17 00:00:00 2001 From: Peter Baumgartner Date: Fri, 12 Oct 2018 11:54:00 +0200 Subject: [PATCH] Added new String extension for simple regex support --- BXSwiftUtils.xcodeproj/project.pbxproj | 12 +++++ BXSwiftUtils/Strings/String+Regex.swift | 53 +++++++++++++++++++ .../Strings/String+RegexTests.swift | 42 +++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 BXSwiftUtils/Strings/String+Regex.swift create mode 100644 BXSwiftUtilsTests/Strings/String+RegexTests.swift diff --git a/BXSwiftUtils.xcodeproj/project.pbxproj b/BXSwiftUtils.xcodeproj/project.pbxproj index 4811076..ab71041 100644 --- a/BXSwiftUtils.xcodeproj/project.pbxproj +++ b/BXSwiftUtils.xcodeproj/project.pbxproj @@ -160,6 +160,10 @@ D0891245215A762200403100 /* CGPoint+String.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0891243215A762200403100 /* CGPoint+String.swift */; }; D089124B215B723C00403100 /* CGRect+String.swift in Sources */ = {isa = PBXBuildFile; fileRef = D089124A215B723C00403100 /* CGRect+String.swift */; }; D089124C215B723C00403100 /* CGRect+String.swift in Sources */ = {isa = PBXBuildFile; fileRef = D089124A215B723C00403100 /* CGRect+String.swift */; }; + D08F44E021708CD90060FBAE /* String+Regex.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08F44DF21708CD90060FBAE /* String+Regex.swift */; }; + D08F44E121708CD90060FBAE /* String+Regex.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08F44DF21708CD90060FBAE /* String+Regex.swift */; }; + D08F44E32170A4850060FBAE /* String+RegexTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08F44E22170A4850060FBAE /* String+RegexTests.swift */; }; + D08F44E42170A4850060FBAE /* String+RegexTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08F44E22170A4850060FBAE /* String+RegexTests.swift */; }; D0C47CE420EE55DA003D3FA3 /* Number+Random.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C47CE320EE55DA003D3FA3 /* Number+Random.swift */; }; D0C47CE520EE55DA003D3FA3 /* Number+Random.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C47CE320EE55DA003D3FA3 /* Number+Random.swift */; }; D0DA3332213DA04A00994E89 /* DispatchGroup+Once.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DA3331213DA04900994E89 /* DispatchGroup+Once.swift */; }; @@ -274,6 +278,8 @@ D0859FDE2158FC7400F624C7 /* NSLocale+FMExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSLocale+FMExtensions.swift"; sourceTree = ""; }; D0891243215A762200403100 /* CGPoint+String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CGPoint+String.swift"; sourceTree = ""; }; D089124A215B723C00403100 /* CGRect+String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CGRect+String.swift"; sourceTree = ""; }; + D08F44DF21708CD90060FBAE /* String+Regex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Regex.swift"; sourceTree = ""; }; + D08F44E22170A4850060FBAE /* String+RegexTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+RegexTests.swift"; sourceTree = ""; }; D0C47CE320EE55DA003D3FA3 /* Number+Random.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Number+Random.swift"; sourceTree = ""; }; D0DA3331213DA04900994E89 /* DispatchGroup+Once.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DispatchGroup+Once.swift"; sourceTree = ""; }; D0EA52D920F8992300A0EF6D /* MTKTextureLoader+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MTKTextureLoader+Extensions.swift"; sourceTree = ""; }; @@ -480,6 +486,7 @@ children = ( 48C248132088CF4100DC9317 /* NSAttributedString+CodableTests.swift */, 48AD6C9F2147FD6400225D9C /* String+UniqueByIncrementingTests.swift */, + D08F44E22170A4850060FBAE /* String+RegexTests.swift */, ); path = Strings; sourceTree = ""; @@ -549,6 +556,7 @@ D03234ED205BFC9F003D6CCB /* String+Localized.swift */, 48AD6C9C2147FCC400225D9C /* String+UniqueByIncrementing.swift */, D046DF87216BAB59004331C3 /* String+DataDetection.swift */, + D08F44DF21708CD90060FBAE /* String+Regex.swift */, 48C2480F2088CE9400DC9317 /* NSAttributedString+Codable.swift */, ); path = Strings; @@ -820,6 +828,7 @@ 4875F2512051EEF5009985EC /* Collection+SafeAccess.swift in Sources */, D0859FD12158F7DD00F624C7 /* URL+Contents.swift in Sources */, 4875F2262051E9D0009985EC /* Array+Concatenation.swift in Sources */, + D08F44E021708CD90060FBAE /* String+Regex.swift in Sources */, D0859FDC2158FBF100F624C7 /* CGSize+String.swift in Sources */, 484FC80020E382A900AA6E3E /* NSMenuItem+ConvenienceInit.swift in Sources */, 48C3DF6520E10DC300359288 /* TypedKVO+propagateChanges.swift in Sources */, @@ -882,6 +891,7 @@ 4875F24F2051ECF9009985EC /* Array+ConcatenationTests.swift in Sources */, 48AD6CA02147FD6400225D9C /* String+UniqueByIncrementingTests.swift in Sources */, 481BE6D62098368E00F12EDF /* Sequence+CompactMap.swift in Sources */, + D08F44E32170A4850060FBAE /* String+RegexTests.swift in Sources */, 4853E3902056D11500938B82 /* BXReadWriteLockTests.swift in Sources */, 48A971E52159122800215F9F /* Enum+Comparable.swift in Sources */, 48C248142088CF4100DC9317 /* NSAttributedString+CodableTests.swift in Sources */, @@ -917,6 +927,7 @@ D03234FE205C2919003D6CCB /* CGRect+Accessors.swift in Sources */, D032350E205C362A003D6CCB /* Date+Components.swift in Sources */, 48B6191F215E35DB00E6E037 /* OptionalType.swift in Sources */, + D08F44E121708CD90060FBAE /* String+Regex.swift in Sources */, 48DA81D1206BCD92009D1E6C /* Collection+Pluck.swift in Sources */, D0C47CE520EE55DA003D3FA3 /* Number+Random.swift in Sources */, D03234EB205BF939003D6CCB /* URL+Info.swift in Sources */, @@ -970,6 +981,7 @@ 4875F27A20529A17009985EC /* Array+ConcatenationTests.swift in Sources */, 48AD6CA12147FD6400225D9C /* String+UniqueByIncrementingTests.swift in Sources */, 481BE6D72098368E00F12EDF /* Sequence+CompactMap.swift in Sources */, + D08F44E42170A4850060FBAE /* String+RegexTests.swift in Sources */, 4853E3912056D11500938B82 /* BXReadWriteLockTests.swift in Sources */, 48A971E62159122800215F9F /* Enum+Comparable.swift in Sources */, 48C248152088CF4100DC9317 /* NSAttributedString+CodableTests.swift in Sources */, diff --git a/BXSwiftUtils/Strings/String+Regex.swift b/BXSwiftUtils/Strings/String+Regex.swift new file mode 100644 index 0000000..afd831c --- /dev/null +++ b/BXSwiftUtils/Strings/String+Regex.swift @@ -0,0 +1,53 @@ +//********************************************************************************************************************** +// +// String+Regex.swift +// Simple regex functions +// Copyright ©2018 Peter Baumgartner. All rights reserved. +// +//********************************************************************************************************************** + + +import Foundation + + +//---------------------------------------------------------------------------------------------------------------------- + + +// MARK: - + +public extension String +{ + + /// Returns any matches for the supplied regex pattern + /// - parameter pattern: A valid regex pattern + /// - parameter options: The options inluence the behavior of the NSRegularExpression + /// - returns: An array of strings matching the regex pattern + + public func regexMatches(for pattern: String, options: NSRegularExpression.Options = []) -> [String] + { + if let regex = try? NSRegularExpression(pattern:pattern, options:options) + { + let string = self as NSString + let range = NSRange(location:0, length:string.length) + + return regex.matches(in:self, options:[], range:range).map + { + string.substring(with: $0.range) + } + } + + return [] + } + + + /// Returns true if a string has at least one match for the supplied regex pattern + + public static func ~= (_ string: String, _ pattern: String) -> Bool + { + return !string.regexMatches(for:pattern).isEmpty + } + +} + + +//---------------------------------------------------------------------------------------------------------------------- diff --git a/BXSwiftUtilsTests/Strings/String+RegexTests.swift b/BXSwiftUtilsTests/Strings/String+RegexTests.swift new file mode 100644 index 0000000..69abf87 --- /dev/null +++ b/BXSwiftUtilsTests/Strings/String+RegexTests.swift @@ -0,0 +1,42 @@ +// +// String+UniqueByIncrementingTests.swift +// BXSwiftUtils +// +// Created by Peter Baumgartner on 12.10.18. +// Copyright © 2018 Boinx Software Ltd. & Imagine GbR. All rights reserved. +// + +import XCTest +import BXSwiftUtils + +class String_RegexTests: XCTestCase +{ + + func testPositive() + { + let str = "Bla Laber ABC Schwafel Sülz" + let matches = str.regexMatches(for:"ABC") + XCTAssertEqual(matches,["ABC"]) + } + + func testNegative() + { + let str = "Bla Laber ABC Schwafel Sülz" + let matches = str.regexMatches(for:"XYZ") + XCTAssertEqual(matches,[]) + } + + func testMatchCount() + { + let str = "Bla ABC Laber ABC Schwafel ABC Sülz" + let matches = str.regexMatches(for:"ABC") + XCTAssertEqual(matches.count,3) + } + + func testOperator() + { + let str = "Bla Laber ABC Schwafel Sülz" + let matches = str ~= "ABC" + XCTAssertEqual(matches,true) + } +}