swift - get value from string using regular expression - ios

I want to extract a value from a string in swift 4.
I tried to use regular expression but it didn't work all i want is to extract the PK value from this query:
"INSERT INTO table(PK,anotherValue) VALUES ('38061','1233')"
I want the result here to be: 38061
the regex i tried:
var results = [String]()
do{
let regex = try NSRegularExpression(pattern:" VALUES ('(.*?)'", options: [])
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]))
}
}
} catch {
print( error)
}
print(results)
i got below error :
Error Domain=NSCocoaErrorDomain Code=2048 "The value “ VALUES
('(.?)'” is invalid." UserInfo={NSInvalidValue= VALUES ('(.?)'

The parentheses are special characters for capturing groups.
To treat a parenthesis as literal character you have to escape it:
pattern:" VALUES \\('(.*?)'"
Please look at:
https://regex101.com/r/lyzoex/1

Related

Convert placeholders such as %1$s to {x} in Swift

I'm parsing an XML doc (using XMLParser) and some of the values have php-like placeholders, e.g. %1$s, and I would like to convert those to {x-1}.
Examples:
%1$s ---> {0}
%2$s ---> {1}
I'm doing this in a seemingly hacky way, using regex:
But there must be a better implementation of this regex.
Consider a string:
let str = "lala fawesfgeksgjesk 3rf3f %1$s rk32mrk3mfa %2$s fafafczcxz %3$s czcz $#$##%## %4$s qqq %5$s"
Now we're going to extract the integer strings between strings % and $s:
let regex = try! NSRegularExpression(pattern: "(?<=%)[^$s]+")
let range = NSRange(location: 0, length: str.utf16.count)
let matches = regex.matches(in: str, options: [], range: range)
matches.map {
print(String(str[Range($0.range, in: str)!]))
}
Works quite fine. The issue is that the "4" value got mixed up because of the preceding random strings before the %4$s.
Prints:
1
2
3
## %4
5
Is there any better way to do this?
This might not be a very efficient (or swifty :)) way but it gets the job done. What it does is that it searches for a given reg ex and uses the matched substring to extract the numeric value and decrease it and then perform a simple replace between the substring and a newly constructed placeholder value. This is executed in a loop until no more matches are found.
let pattern = #"%(\d*)\$s"#
while let range = str.range(of: pattern, options: .regularExpression) {
let placeholder = str[range]
let number = placeholder.trimmingCharacters(in: CharacterSet(charactersIn: "0123456789.").inverted)
if let value = Int(number) {
str = str.replacingOccurrences(of: placeholder, with: "{\(value - 1)}")
}
}

Return range with first and last character in string

I have a string: "Hey #username that's funny". For a given string, how can I search the string to return all ranges of string with first character # and last character to get the username?
I suppose I can get all indexes of # and for each, get the substringToIndex of the next space character, but wondering if there's an easier way.
If your username can contain only letters and numbers, you can use regular expression for that:
let s = "Hey #username123 that's funny"
if let r = s.rangeOfString("#\\w+", options: NSStringCompareOptions.RegularExpressionSearch) {
let name = s.substringWithRange(r) // #username123"
}
#Vladimir's answer is correct, but if you're trying to find multiple occurrences of "username", this should also work:
let s = "Hey #username123 that's funny"
let ranges: [NSRange]
do {
// Create the regular expression.
let regex = try NSRegularExpression(pattern: "#\\w+", options: [])
// Use the regular expression to get an array of NSTextCheckingResult.
// Use map to extract the range from each result.
ranges = regex.matchesInString(s, options: [], range: NSMakeRange(0, s.characters.count)).map {$0.range}
}
catch {
// There was a problem creating the regular expression
ranges = []
}
for range in ranges {
print((s as NSString).substringWithRange(range))
}

How to get value from point(a b) swift

I have this kind of string: "POINT(101.650577657408 3.1653186153213)".
Anyone know how can I get the first and second value of POINT from this String?
You can easily spit the string using componentsSeparatedByString function.
let myStr = "POINT(101.650577657408 3.1653186153213)"
let characterSet = NSCharacterSet(charactersInString: "( )")
var splitString = myStr.componentsSeparatedByCharactersInSet(characterSet)
print(splitString[0])
print(splitString[1])
print(splitString[2])
The above only works if you have the complete one String.
Although the NSCharacterSet solution is correct but here is another solution using the most powerful regex.
var error: NSError?
// Initialise the regex for a float value
let regex: NSRegularExpression = NSRegularExpression(pattern: "(\\d*\\.\\d*)", options: NSRegularExpressionOptions.CaseInsensitive, error: &error)!
// Matches array contains all the match found for float in given string
let matches: NSArray = regex.matchesInString(str as String, options: NSMatchingOptions.ReportProgress, range: NSMakeRange(0, str.length))
// You can easily get all values by enumeration
for match in matches {
println(str.substringWithRange(match.range))
}
The benefit of this solution is it will scan all the float values and will also work in case of pattern got changed.
Try this, this will work for your string
let myStr = "POINT(101.650577657408 3.1653186153213)"
let strWithout_POINT_openingBrace = myStr.stringByReplacingOccurrencesOfString("POINT(", withString: "")//"101.650577657408 3.1653186153213)"
let strWithout_closingBrace = strWithout_POINT_openingBrace.stringByReplacingOccurrencesOfString(")", withString: "")//"101.650577657408 3.1653186153213"
//now you have only space between two values
//so split string by space
let arrStringValues = strWithout_closingBrace.componentsSeparatedByString(" ");//["101.650577657408","3.1653186153213"]
print(arrStringValues[0]);//first value "101.650577657408"
print(arrStringValues[1]);//second value "3.1653186153213"

Array cleaning in Swift

I have an array in Swift:
["\"100003866283798-2\"", "\"100001986741004-2\"",
"\"100003455181526-2\"", "\"100002261472542-2\"",
"\"100003866283798-3\"", "\"100003866283798-0\"",
"\"100001986741004-3\"", "\"100001986741004-0\"",
"\"100003455181526-3\"", "\"100003455181526-0\"",
"\"100002261472542-3\"", "\"100002261472542-0\""]
and I only want the numbers, not the quotes and the -2.
I can't figure out to do this, because when I type
let cleanStr = numberArray.stringByReplacingOccurrencesOfString("\"", withString: "", options: nil, range: nil)
it gives the error:
Value of type '[String]' has no member
'stringByReplacingOccurrencesOfString'
I know it's very confusing with all the quotes etc but I want these numbers without their quotes etc, anyone a solution?
You can do it like this:
let newArray = array.map { (string: String) -> String in
let woFirst = string.characters.dropFirst()
let tilDash = woFirst.prefixUpTo(
woFirst.indexOf("-") ?? woFirst.endIndex)
return String(tilDash)
}
(Weirdly it doesn't compile without the type annotation). Or if you feel fancy:
let newArray = array
.map{ {$0.prefixUpTo($0.indexOf("-") ?? $0.endIndex)}($0.characters.dropFirst()) }
.map(String.init)
(XCode 7 beta 6)
stringByReplacingOccurrencesOfString
works only with NSString not Array. Then you must iterate your array remove excess char.

Extract a whole word from string In Swift

for example I have a String text like : "I have to go to the kitchen"
and If I searched this text using the 'av' phrase I want a way that return me the whole word 'have'
how I can do this in swift
There is very nice solution with filter in swift.You can use rangeOfString method of String with filter to get only filtered string having "av"
var s = "I have to go to the kitchen"
//will return "have"
let abc:[String] = s.componentsSeparatedByString(" ").filter({ $0.rangeOfString("av", options: NSStringCompareOptions.CaseInsensitiveSearch, range: nil, locale: nil) != nil } )
There is an API for that, enumerateSubstrings(in:options:using:)
The byWords option returns all words in the closure
let string = "I have to go to the kitchen"
var found : String?
string.enumerateSubstrings(in: string.startIndex..., options: .byWords) { substring, _, _, stop in
if let word = substring, word.contains("av") {
found = word
stop = true
}
}
print(found ?? "not found")
Split your string into array by space char (" "), and return component that contains your 'av' string.
let words = stringYouWantToSearchIn.componentsSeparatedByString(" ")
for word in words
{
var range = word.rangeOfString(lastWord)
if (range != nil)
{
//you got what do you want in 'word variable'
break
}
}

Resources