Swift - Regular Expression to match parentheses - ios

I am trying to use regex to search through a string: "K1B92 (D) [56.094]" and I want to grab the "(D)" including the parentheses surrounding the "D". I am having trouble finding the correct expression to match the actual parentheses as simply putting parentheses will take it as a block and trying to escape the parentheses with "\" making it think its an expression to be evaluated. I also tried escaping "\(" with "\\(" as so: "\\([ABCD])\\)" but without luck. This is the code I have been using:
let str = "K1B92 (D) [56.094]"
let regex = NSRegularExpression(pattern: "\\b\\([ABCD])\\)\\b", options: NSRegularExpressionOptions.CaseInsensitive, error: nil)
let match = regex?.firstMatchInString(str, options: NSMatchingOptions.WithoutAnchoringBounds, range: NSMakeRange(0, count(str)))
let strRange = match?.range
let start = strRange?.location
let length = strRange?.length
let subStr = str.substringWithRange(Range<String.Index>(start: advance(str.startIndex, start!), end: advance(str.startIndex, start! + length!)))
// "\\b\([ABCD])\)\\b" returns range only for the letter "D" without parentheses.
// "\\b\\([ABCD])\\)\\b" returns nil
Can direct me towards the correct expression please? Thank you very much.

The \\([ABCD])\\) part is OK,
Correction: As #vacawama correctly said in his answer, the parentheses
do not match here. \\([ABCD]\\) matches one of the letters A-D
enclosed in parentheses.
The other problem is that there is no word boundary
(\b pattern) between a space and a parenthesis.
So you could either (depending on your needs), just remove the \b patterns, or replace them by \s for white space:
let regex = NSRegularExpression(pattern: "\\s\\([ABCD]\\)\\s", ...
But since the matched string should not include the space you need
a capture group:
let regex = NSRegularExpression(pattern: "\\s(\\([ABCD]\\))\\s", ...
// ...
let strRange = match?.rangeAtIndex(1)

The regular expression you need is "\\([ABCD]\\)". You need the double escape \\ before both open paren ( and close paren ).

Related

Regex to not allow staring whitespace in string swift ios

I want to create regex thats allows characters numbers and spaces but not at the begning of string , i have created below one but its not working "^\\S.*[^A-Za-z0-9_ ].*".
Swift:
func containsAllowedCharacters(regex: String?, stringToCheck: String) -> Bool {
var isValid = false
if let regex = regex {
let testString = NSPredicate(format: "SELF MATCHES %#", regex)
isValid = testString.evaluate(with: stringToCheck)
}
return !isValid
}
Your pattern, ^\S.*[^A-Za-z0-9_ ].*, matches start of string with ^, then matches any non-whitespace char with \S (note it matches any punctuation, letters and digits), then matches any zero or more chars other than line break chars as many as possbile with .*, then matches any char other than an ASCII letter, digit, _ or space, and then again matches any zero or more chars other than line break chars as many as possbile with .*.
As you see, all the pattern parts match more than you allow. Also, pay attention you actually require at least two chars to be present with this pattern while your code implies you need to support zero length string, too.
You can use
let FileNameRegex = #"^(?!\s)[A-Za-z0-9_\s]*$"#
NOTE: As you are using it with MATCHES in the NSPredicate.evaluate, you do not need the ^ and $ anchors on both ends since MATCHES requires a full string match:
let FileNameRegex = #"(?!\s)[A-Za-z0-9_\s]*"#
let testString = NSPredicate(format: "SELF MATCHES %#", regex)
Note the use of #"..."# notation that makes a raw string literal, where a single backslash is parsed as a literal backslash.
The pattern matches
^ - start of string
(?!\s) - a negative lookahead that matches a location in string that is not immediately followed with a whitespace
[A-Za-z0-9_\s]* - zero or more (due to the * quantifier) ASCII letters, digits, underscores and whitespaces
$ - end of string.
You are looking for lookaheads:
^(?! )[ \w]+$
\w is a short form for [\p{Alphabetic}\p{Mark}\p{Decimal_Number}\p{Connector_Punctuation}\u200c\u200d] (see here and here for more information) as it is used very often, but see #Wiktor's comment for a more precise clarification.
Also,see a demo on regex101.com.

Combine multiple replacingOccurrences() with Swift

I have a String, I would like to add backslash to specific characters, because I use markdown and I don't wand to add style it's not wanted.
I tried to make a function, and it's working, but it's not efficient I guess:
func escapeMarkdownCharacters(){
let myString = "This is #an exemple #of _my_ * function"
var modString = myString.replacingOccurrences(of: "#", with: "\\#")
modString = modString.replacingOccurrences(of: "*", with: "\\*")
modString = modString.replacingOccurrences(of: "_", with: "\\_")
print(modString) // Displayed: This is \#an exemple \#of \_my\_ \* function
}
I would like to only have one "replacingOccurences" that work for multiple characters. I think I could do that with regex but I didn't figure out how. If you have an idea, please share it with me.
You may use
var modString = myString.replacingOccurrences(of: "[#*_]", with: "\\\\$0", options: [.regularExpression])
With a raw string literal:
var modString = myString.replacingOccurrences(of: "[#*_]", with: #"\\$0"#, options: [.regularExpression])
Result: This is \#an exemple \#of \_my\_ \* function
The options: [.regularExpression] argument enables the regex search mode.
The [#*_] pattern matches #, * or _ and then each match is replaced with a backslash (\\\\) and the match value ($0). Note that the backslash must be doubled in the replacement string because a backslash has a special meaning inside a replacement pattern (it may be used to make $0 a literal string when $ is preceded with a backslash).

Find a word after and before a string

I have a string like so...
ab-0-myCoolApp.theAppAB.in
How can I get the word myCoolApp from this string...? Also there are many strings in the same format i.e myCoolApp can be myCoolAppABX or myCoolAppABCD etc.
that could be a really brief solution (=one of the many ones) to your problem, but the core concept would be something like that in every case.
the input has some random values:
let inputs = ["ab-0-myCoolApp.theAppAB.in", "ab-0-myCoolAppABX.theAppAB.in", "ab-0-myCoolAppABXC.theAppAB.in"]
and having a regular expression to find matches:
let regExp = try? NSRegularExpression(pattern: "-([^-]*?)\\.", options: NSRegularExpression.Options.caseInsensitive)
then Release the Kraken:
inputs.forEach { string in
regExp?.matches(in: string, options: NSRegularExpression.MatchingOptions.reportProgress, range: NSMakeRange(0, string.lengthOfBytes(using: .utf8))).forEach({
let match = (string as NSString).substring(with: $0.range(at: 1))
debugPrint(match)
})
}
finally it prints out the following list:
"myCoolApp"
"myCoolAppABX"
"myCoolAppABXC"
NOTE: you may need to implement further failsafes during getting the matches or you can refactor the entire idea at your convenience.

swift ios alpha numeric regex that allows underscores and dashes

I am using this lib for validation and are trying to add my own regex.
What I want to do is to make a regex that allows alphanumeric A-Z 0-9 together with dashes and unserscores -_
I have tryed let regex = "[a-zA-Z0-9_-]" but I cant get it to work.
I also want the regex to not only allow english letters, but all languishes.
The lib works cause I have made another regex that only allows ints 0-9 which works
let intRegex = "^[0-9]*$"
Your regex look good but it will only match a single character. Do this "^[a-zA-Z0-9_-]*$" instead to match more than one character.
breakup --
^ -- start of string
[\pL0-9_-] -- characters you want to allow
* -- any number of characters (the crucial bit you were missing)
$ -- end of string
Building up on #charsi's answer
extension String {
var isAlphanumericDashUnderscore: Bool {
get {
let regex = try! NSRegularExpression(pattern: "^[a-zA-Z0-9_-]*$", options: .caseInsensitive)
return regex.firstMatch(in: self, options: [], range: NSRange(location: 0, length: count)) != nil
}
}
}

Swift regex to match unicodes

I am new to swift and want to match all the unicode strings using regex
For example:
var s="😀 emoji 😀"
When I decoded the above string the result is:
"\ud83d\ude00 emoji \ud83d\ude00"
I want to replace each emoji with say *
In java I used the regex as:
"[\uD800-\uDBFF\uDC00-\uDFFF]" and was working
In swift I am using the same regex but its replacing every character with *
I want the result as * emoji *
Help is highly appreciated
The Unicode code point of the emoji you have shown is U+1F600.
(Unicode 9.0 Character Code Charts - Emoticons)
And your regex pattern (which may work for UTF-16 representation) [\uD800-\uDBFF\uDC00-\uDFFF] matches all non-BMP characters -- U+10000...U+10FFFF, which contains most of all emojis but also contains huge non-emoji characters.
So, as you say "[\uD800-\uDBFF\uDC00-\uDFFF]" was working, the equivalent pattern in NSRegularExpression is "[\\U00010000-\\U0010FFFF]".
var s="😀 emoji 😀"
let regex = try! NSRegularExpression(pattern: "[\\U00010000-\\U0010FFFF]", options: [])
let replaced = regex.stringByReplacingMatchesInString(s, options: [], range: NSRange(0..<s.utf16.count), withTemplate: "*") //->"* emoji *"
(Addition)
To see Unicode code points in your string literal:
s.unicodeScalars.forEach {
print(String(format: "U+%04X ", Int($0.value)))
}
For your example string, I get:
U+1F600
U+0020
U+0065
U+006D
U+006F
U+006A
U+0069
U+0020
U+1F600

Resources