Regex used in swift to check decimal input - ios

In my application, there are a few textfields with decimal keyboard input. So I need a function to validate the number.
func valueCheck(check: Double) -> Double{
let myRegex = "^(?:|0|[1-9]\\d*)(?:\\.\\d*)?$"
if check != nil && let match = check.rangeOfString(myRegex, options: .RegularExpressionSearch){
return check
}else{
return 0.0
}
}
If the number is not nil or invalid such as a few dots, then return the number. If the number is nil or invalid then return 0.0
I want to use regex but I have no idea how to use it in swift. Any help appreciated.

class func regexMatch(source:String,regexStr:String) -> Bool{
let regex: NSRegularExpression?
do{
try regex = NSRegularExpression(
pattern: regexStr,
options: .CaseInsensitive)
}catch{
return false
}
if let matches = regex?.matchesInString(source,
options: NSMatchingOptions(rawValue: 0),
range: NSMakeRange(0, source.characters.count)) {
return matches.count > 0
} else {
return false
}
}

Swift 2
import Foundation
func valueCheck(d: Double) -> Double {
var result = 0.0
do {
let regex = try NSRegularExpression(pattern: "^(?:|0|[1-9]\\d*)(?:\\.\\d*)?$", options: [])
let results = regex.matchesInString(String(d), options:[], range: NSMakeRange(0, String(d).characters.count))
if results.count > 0 {result = d}
} catch let error as NSError {
print("invalid regex: \(error.localizedDescription)")
}
return result
}
Swift 3
import Foundation
func valueCheck(_ d: Double) -> Double {
var result = 0.0
do {
let regex = try RegularExpression(pattern: "^(?:|0|[1-9]\\d*)(?:\\.\\d*)?$", options: [])
let results = regex.matches(in: String(d), options: [], range: NSMakeRange(0, String(d).characters.count))
if results.count > 0 {result = d}
} catch let error as NSError {
print("invalid regex: \(error.localizedDescription)")
}
return result
}

Related

Paste (Insert) into Label (IOS) only the numbers of String

I have code to implement the "Paste" function.
But there is an insertion of all symbols and not only numbers.
How can I make it so that I can insert only numbers ???
Creating an Extension file:
Swift extension example
Past (Photo)
Updated code
actionSheetController.addAction(
UIAlertAction(title: NSLocalizedString("Past", comment: ""), style: .default, handler: { [weak self] _ in
guard let strongSelf = self else { return }
strongSelf.displayResultLabel.text = UIPasteboard.general.string.onlyNumbers()
print ("Past")
})
)
extension String {
func onlyNumbers() ->String{
do{
let regex = try NSRegularExpression(pattern: "([//.,\\d])*", options:[.dotMatchesLineSeparators])
var result : String = ""
for resultMatch in regex.matches(in: self, options: NSRegularExpression.MatchingOptions.init(rawValue: 0), range: NSMakeRange(0, NSString(string: self).length)) {
result += NSString(string: self).substring(with: resultMatch.range)
}
return result
}
catch
{
}
return ""
}
}
Use this extension with regex function to get only the numbers of your String
extension String {
func onlyNumbers() ->String{
do{
let regex = try NSRegularExpression(pattern: "([//.,\\d])*", options:[.dotMatchesLineSeparators])
var result : String = ""
for resultMatch in regex.matches(in: self, options: NSRegularExpression.MatchingOptions.init(rawValue: 0), range: NSMakeRange(0, NSString(string: self).length)) {
result += NSString(string: self).substring(with: resultMatch.range)
}
return result
}
catch
{
}
return ""
}
}
you can use it like this
actionSheetController.addAction(
UIAlertAction(title: NSLocalizedString("Past", comment: ""), style: .default, handler: { [weak self] _ in
guard let strongSelf = self else { return }
strongSelf.displayResultLabel.text = UIPasteboard.general.string.onlyNumbers()
print ("Past")
})
)

regex to get string between two % characters

I need to extract string between two "%" characters, multiple occurrences can be present in the query string.
now am using the following regex, can somebody help to get the exact Regax format.
let query = "Hello %test% ho do you do %test1%"
let regex = try! NSRegularExpression(pattern:"%(.*?)%", options: [])
if let results = regex?.matchesInString(query, options: .Anchored, range: NSMakeRange(0,query.characters.count)){
for match in results{
}
}
Your pattern is fine but your code didn't compile. Try this instead:
Swift 4
let query = "Hello %test% how do you do %test1%"
let regex = try! NSRegularExpression(pattern:"%(.*?)%", options: [])
var results = [String]()
regex.enumerateMatches(in: query, options: [], range: NSMakeRange(0, query.utf16.count)) { result, flags, stop in
if let r = result?.range(at: 1), let range = Range(r, in: query) {
results.append(String(query[range]))
}
}
print(results) // ["test", "test1"]
NSString uses UTF-16 encoding so NSMakeRange is called with the number of UTF-16 code units.
Swift 2
let query = "Hello %test% how do you do %test1%"
let regex = try! NSRegularExpression(pattern:"%(.*?)%", options: [])
let tmp = query as NSString
var results = [String]()
regex.enumerateMatchesInString(query, options: [], range: NSMakeRange(0, tmp.length)) { result, flags, stop in
if let range = result?.rangeAtIndex(1) {
results.append(tmp.substringWithRange(range))
}
}
print(results) // ["test", "test1"]
Getting a substring out of Swift's native String type is somewhat of a hassle. That's why I casted query into an NSString
I have written a method for regular express. Your regex is fine. You can test your regexes here . The method is:
func regexInText(regex: String!, text: String!) -> [String] {
do {
let regex = try NSRegularExpression(pattern: regex, options: [])
let nsString = text as NSString
let results = regex.matchesInString(text,
options: [], range: NSMakeRange(0, nsString.length))
return results.map { nsString.substringWithRange($0.range)}
} catch let error as NSError {
print("invalid regex: \(error.localizedDescription)")
return []
}
}
You can call it whereever you want.

how i get an int from string?

am working on a weather app and i want to generate the image according to the degrees number witch is in a string so how can i extract the number from string
this is the string:
Mostly dry. Very mild (max 19ºC on Sat afternoon, min 15ºC on Sunnight). Wind will be generally light.
#IBAction func weatherButton(sender: UIButton) {
let url = NSURL(string: "http://www.weather-forecast.com/locations/" + cityNameTextField.text.stringByReplacingOccurrencesOfString(" ", withString: "-") + "/forecasts/latest")
if url != nil {
let task = NSURLSession.sharedSession().dataTaskWithURL(url!){ (data, response, error) in
var urlError = false
var weather = ""
if error == nil {
var urlContent = NSString(data: data, encoding: NSUTF8StringEncoding)
var urlContentArray = urlContent!.componentsSeparatedByString("<span class=\"phrase\">")
if urlContentArray.count > 0 {
var weatherArray = urlContentArray[1].componentsSeparatedByString("</span>")
weather = weatherArray[0] as! String
weather = weather.stringByReplacingOccurrencesOfString("°", withString: "º")
println(weather)
}
else {
urlError = true
}
}
else {
urlError = true
}
dispatch_async(dispatch_get_main_queue()) {
if urlError == true {
self.showError()
}
else {
self.weatherFact.text = weather
}
}
}
task.resume()
}
else {
showError()
}
}
Another solution using NSRegularExpression.
The result is an Array of the numbers and the regex considers also temperatures below zero
For Swift 1.2:
let string = "Mostly dry. Very mild (max -19ºC on Sat afternoon, min 15ºC on Sunnight). Wind will be generally light."
let regex = NSRegularExpression(pattern: "-?[0-9]{1,3}", options: NSRegularExpressionOptions(), error: nil)
if let matches = regex?.matchesInString(string, options: NSMatchingOptions(), range: NSRange(location:0, length:count(string))) {
let degrees = matches.map {return (string as NSString).substringWithRange($0.range).toInt()! }
println(degrees) // -> [-19, 15]
}
For Swift 2.0:
let string = "Mostly dry. Very mild (max -19ºC on Sat afternoon, min 15ºC on Sunnight). Wind will be generally light."
do {
let regex = try NSRegularExpression(pattern: "-?[0-9]{1,3}", options: NSRegularExpressionOptions())
let matches = regex.matchesInString(string, options: NSMatchingOptions(), range: NSRange(location: 0, length: string.characters.count))
let degrees = matches.map {Int((string as NSString).substringWithRange($0.range))!}
print(degrees) // -> [-19, 15]
}
catch {
print("NSRegularExpression threw error: \(error)")
}

Regular expression to get URL in string swift with Capitalized symbols

I try to get URLs in text. So, before, I used such an expression:
let re = NSRegularExpression(pattern: "https?:\\/.*", options: nil, error: nil)!
But I had a problem when a user input URLs with Capitalized symbols (like Http://Google.com, it doesn't match it).
I tried:
let re = NSRegularExpression(pattern: "(h|H)(t|T)(t|T)(p|P)s?:\\/.*", options: nil, error: nil)!
But nothing happened.
You turn off case sensitivity using an i inline flag in regex, see Foundation Framework Reference for more information on available regex features.
(?ismwx-ismwx)
Flag settings. Change the flag settings. Changes apply to the portion of the pattern following the setting. For example, (?i) changes to a case insensitive match.The flags are defined in Flag Options.
For readers:
Matching an URL inside larger texts is already a solved problem, but for this case, a simple regex like
(?i)https?://(?:www\\.)?\\S+(?:/|\\b)
will do as OP requires to match only the URLs that start with http or https or HTTPs, etc.
Swift 4
1. Create String extension
import Foundation
extension String {
var isValidURL: Bool {
guard !contains("..") else { return false }
let head = "((http|https)://)?([(w|W)]{3}+\\.)?"
let tail = "\\.+[A-Za-z]{2,3}+(\\.)?+(/(.)*)?"
let urlRegEx = head+"+(.)+"+tail
let urlTest = NSPredicate(format:"SELF MATCHES %#", urlRegEx)
return urlTest.evaluate(with: trimmingCharacters(in: .whitespaces))
}
}
2. Usage
"www.google.com".isValidURL
Try this - http?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?
let pattern = "http?://([-\\w\\.]+)+(:\\d+)?(/([\\w/_\\.]*(\\?\\S+)?)?)?"
var matches = [String]()
do {
let regex = try NSRegularExpression(pattern: pattern, options: NSRegularExpressionOptions(rawValue: 0))
let nsstr = text as NSString
let all = NSRange(location: 0, length: nsstr.length)
regex.enumerateMatchesInString(text, options: NSMatchingOptions.init(rawValue: 0), range: all, usingBlock: { (result, flags, _) in
matches.append(nsstr.substringWithRange(result!.range))
})
} catch {
return [String]()
}
return matches
Make an exension of string
extension String {
var isAlphanumeric: Bool {
return rangeOfString( "^[wW]{3}+.[a-zA-Z]{3,}+.[a-z]{2,}", options: .RegularExpressionSearch) != nil
}
}
call using like this
"www.testsite.edu".isAlphanumeric // true
"flsd.testsite.com".isAlphanumeric //false
My complex solution for Swift 5.x
ViewController:
private func loadUrl(_ urlString: String) {
guard let url = URL(string: urlString) else { return }
let request = URLRequest(url: url)
webView.load(request)
}
UISearchBarDelegate:
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
guard let text = searchBar.text else { return }
if !text.isUrl() {
let finalUrl = String(format: "%#%#", "https://www.google.com/search?q=", text)
loadUrl(finalUrl)
return
}
if text.starts(with: "https://") || text.starts(with: "http://") {
loadUrl(text)
return
}
let finalUrl = String(format: "%#%#", "https://", text)
loadUrl(finalUrl)
}
String extension:
extension String {
func isUrl() -> Bool {
guard !contains("..") else { return false }
let regex = "((http|https)://)?([(w|W)]{3}+\\.)?+(.)+\\.+[A-Za-z]{2,3}+(\\.)?+(/(.)*)?"
let urlTest = NSPredicate(format:"SELF MATCHES %#", regex)
return urlTest.evaluate(with: trimmingCharacters(in: .whitespaces))
}
}

Call can throw, but it is not marked with 'try' and the error is not handled: NSRegularExpression

I have written this function in String Extension and can't figure out the error.
func isEmail() -> Bool {
let regex = NSRegularExpression(pattern: "^[A-Z0-9._%+-]+#[A-Z0-9.-]+\\.[A-Z]{2,4}$", options: [.CaseInsensitive])
return regex.firstMatchInString(self, options: nil, range: NSMakeRange(0, characters.count)) != nil
}
The error is:
Call can throw, but it is not marked with 'try' and the error is not handled
NSRegularExpression(pattern:) throws an error if the pattern is invalid. In your case, the pattern is fixed, so an invalid pattern
would be a programming error.
This is a use-case for the "forced-try" expression with try!:
extension String {
func isEmail() -> Bool {
let regex = try! NSRegularExpression(pattern: "^[A-Z0-9._%+-]+#[A-Z0-9.-]+\\.[A-Z]{2,4}$",
options: [.CaseInsensitive])
return regex.firstMatchInString(self, options:[],
range: NSMakeRange(0, utf16.count)) != nil
}
}
try! disables the error propagation so that the method does not
throw an error (which the caller has to catch). It will abort with a
runtime exception if the pattern is invalid, which helps to find
programming errors early.
Note also that NSRange() counts the length of NSString, i.e. the number of UTF-16 code points, so
characters.count should be utf16.count, otherwise it might crash
e.g. with Emoji characters.
That's because that initializer can now throw an exception, so you need to try to call it and be prepared to catch the exception. You can do this by adding try before the initializer and annotating your method with throws.
extension String {
func isEmail() throws -> Bool {
let regex = try NSRegularExpression(pattern: "^[A-Z0-9._%+-]+#[A-Z0-9.-]+\\.[A-Z]{2,4}$", options: [.CaseInsensitive])
return regex.firstMatchInString(self, options: NSMatchingOptions(rawValue: 0), range: NSMakeRange(0, characters.count)) != nil
}
}
Then when you want to call the method, do it from within a do block and catch the error that comes out.
do {
try "person#email.com".isEmail()
} catch {
print(error)
}
Note: I've also updated your regex.firstMatchInString call to reflect the fact that the options parameter can no longer take a nil value.
If you don't like try catch :
extension String {
func matchPattern(patStr:String)->Bool {
var isMatch:Bool = false
do {
let regex = try NSRegularExpression(pattern: patStr, options: [.CaseInsensitive])
let result = regex.firstMatchInString(self, options: NSMatchingOptions(rawValue: 0), range: NSMakeRange(0, characters.count))
if (result != nil)
{
isMatch = true
}
}
catch {
isMatch = false
}
return isMatch
}
}
check string is correct email format :
let emailInput:String = "checkthis#gmail.com"
if (emailInput.matchPattern("^[A-Z0-9._%+-]+#[A-Z0-9.-]+\\.[A-Z]{2,4}$"))
{
print("this is e-mail!")
}
You could use string.rangeOfString, and specify the option to .RegularExpressionSearch. It's simple.
func isEmail(email: String) -> Bool {
return email.rangeOfString("^[A-Z0-9a-z._%+-]+#[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}$", options: .RegularExpressionSearch) != nil
}

Resources