How to check whether a WHOLE string can be matches to regex? In Java is method String.matches(regex)

- 607,720
- 39
- 448
- 563

- 295
- 1
- 3
- 11
-
Do you only need a boolean as a result? – Wiktor Stribiżew Apr 28 '17 at 09:10
-
Yes, I only need a Bool result – Kamil Sebastian Góralski Apr 28 '17 at 09:19
-
Well, I doubt there is a specific *method* for it, can't you use `^` and `$` anchors with your pattern? I mean, do you define the pattern or is it user-defined? – Wiktor Stribiżew Apr 28 '17 at 09:24
-
I have defined a pattern and I check whether text introduced by user in TextField matches to a pattern – Kamil Sebastian Góralski Apr 28 '17 at 09:34
-
Ok, you need to just use `^` and `$` to define the start and end positions. There is `.anchored` option, but it works as `/A` in PHP, only anchors at the start of the string. – Wiktor Stribiżew Apr 28 '17 at 09:40
3 Answers
You need to use anchors, ^
(start of string anchor) and $
(end of string anchor), with range(of:options:range:locale:)
, passing the .regularExpression
option:
import Foundation
let phoneNumber = "123-456-789"
let result = phoneNumber.range(of: "^\\d{3}-\\d{3}-\\d{3}$", options: .regularExpression) != nil
print(result)
Or, you may pass an array of options, [.regularExpression, .anchored]
, where .anchored
will anchor the pattern at the start of the string only, and you will be able to omit ^
, but still, $
will be required to anchor at the string end:
let result = phoneNumber.range(of: "\\d{3}-\\d{3}-\\d{3}$", options: [.regularExpression, .anchored]) != nil
See the online Swift demo
Also, using NSPredicate
with MATCHES
is an alternative here:
The left hand expression equals the right hand expression using a regex-style comparison according to ICU v3 (for more details see the ICU User Guide for Regular Expressions).
MATCHES
actually anchors the regex match both at the start and end of the string (note this might not work in all Swift 3 builds):
let pattern = "\\d{3}-\\d{3}-\\d{3}"
let predicate = NSPredicate(format: "self MATCHES [c] %@", pattern)
let result = predicate.evaluate(with: "123-456-789")

- 7,431
- 18
- 59
- 84

- 607,720
- 39
- 448
- 563
What you are looking for is range(of:options:range:locale:)
then you can then compare the result of range(of:option:) with whole range of comparing string..
Example:
let phoneNumber = "(999) 555-1111"
let wholeRange = phoneNumber.startIndex..<phoneNumber.endIndex
if let match = phoneNumber.range(of: "\\(?\\d{3}\\)?\\s\\d{3}-\\d{4}", options: .regularExpression), wholeRange == match {
print("Valid number")
}
else {
print("Invalid number")
}
//Valid number
Edit: You can also use NSPredicate
and compare your string with evaluate(with:)
method of its.
let pattern = "^\\(?\\d{3}\\)?\\s\\d{3}-\\d{4}$"
let predicate = NSPredicate(format: "self MATCHES [c] %@", pattern)
if predicate.evaluate(with: "(888) 555-1111") {
print("Valid")
}
else {
print("Invalid")
}

- 71,513
- 12
- 161
- 183
-
I think `"\\(?\\d{3}\\)?\\s\\d{3}-\\d{4}"` will also allow partial matches. Add `^` and `$` anchors on both sides of the pattern. – Wiktor Stribiżew Apr 28 '17 at 09:16
-
-
1Yeah, I thought about that, too. I think there is still another way, but can't find a way to make NSPredicate work in Swift 3. It is really misfortunate that `.anchored` only anchors at the string start. – Wiktor Stribiżew Apr 28 '17 at 10:06
-
@WiktorStribiżew Thanks for remind me about `NSPredicate`, edited answer with that also – Nirav D Apr 28 '17 at 10:25
-
-
If you have an idea how to make it work everywhere, it would be the best approach. – Wiktor Stribiżew Apr 28 '17 at 10:30
-
@WiktorStribiżew Have you tried once running on Xcode because it looks like this bug with linux check this one https://bugs.swift.org/browse/SR-957 – Nirav D Apr 28 '17 at 10:41
-
1No, it is not [the only issue](http://rextester.com/ZCLMM88063). Mabe the NSPredicate was not ready in Swift 3.0.2. – Wiktor Stribiżew Apr 28 '17 at 10:44
-
with little bit of edit
import Foundation
func matches(for regex: String, in text: String) -> Bool {
do {
let regex = try NSRegularExpression(pattern: regex)
let nsString = text as NSString
let results = regex.matches(in: text, range: NSRange(location: 0, length: nsString.length))
return !results.isEmpty
} catch let error {
print("invalid regex: \(error.localizedDescription)")
return false
}
}
Example usage from link above:
let string = "19320"
let matched = matches(for: "^[1-9]\\d*$", in: string)
print(matched) // will match
let string = "a19320"
let matched = matches(for: "^[1-9]\\d*$", in: string)
print(matched) // will not match