NSRegularExpression search string "*string*" - ios

i have a list of string i want search string like A mean it is only appearance in middle not first or last.My code here:
When i run all 3 case is true, but only case "う上あ" is true
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSArray *array = #[#"上あう", #"う上あ", #"あう上"];
NSString *stringNeedToFind = #"*上*";
for (NSString *string in array) {
if ([[self regularExpressionFromValue: stringNeedToFind] numberOfMatchesInString:string options: 0 range: NSMakeRange(0, string.length)]) {
NSLog(#"String containt.");
}
}
}
- (NSRegularExpression *) regularExpressionFromValue: (NSString *) value
{
NSString *pattern = [NSRegularExpression escapedPatternForString: value];
pattern = [pattern stringByReplacingOccurrencesOfString: #"\\*" withString: #".*"];
pattern = [pattern stringByReplacingOccurrencesOfString: #"\\?" withString: #"."];
pattern = [pattern stringByReplacingOccurrencesOfString: #".*.*.*" withString: #"\\*"];
pattern = [pattern stringByReplacingOccurrencesOfString: #"..." withString: #"\\?\\?\\?"];
pattern = [NSString stringWithFormat: #"^%#$", pattern];
return [NSRegularExpression regularExpressionWithPattern: pattern options: 0 error: NULL];
}

As far as I know, the asterisk (*) is used as an operator to check if a character (set) is present 0 or more times. I think you should use the plus character (+), e.g. like this: ^.+上.+$, meaning there should be 1 or more characters at the start and at the end.

Related

Regex for a string combination

NSString *fmtpAudio = #"a=fmtp:111 ";
NSString *stereoString = #";stereo=1;sprop-stereo=1";
NSArray *componentArray = [localSdpMutableStr componentsSeparatedByString:fmtpAudio];
if (componentArray.count >= 2) {
NSString *component = [componentArray objectAtIndex: 1];
NSArray *fmtpArray = [component componentsSeparatedByString:#"\r\n"];
if (fmtpArray.count > 1) {
NSString *fmtp = [fmtpArray firstObject];
NSString *fmtpAudioOld = [NSString stringWithFormat:#"%#%#", fmtpAudio, fmtp];
fmtpAudio = [NSString stringWithFormat:#"%#%#%#", fmtpAudio, fmtp, stereoString];
NSString *stereoEnabledSDP = [NSString stringWithString: localSdpMutableStr];
stereoEnabledSDP = [stereoEnabledSDP stringByReplacingOccurrencesOfString: fmtpAudioOld withString: fmtpAudio];
localSdpMutableStr.string = stereoEnabledSDP;
}
}
Consider below example String:
a=fmtp:93 av=2\r\n
a=fmtp:111 av=1\r\n
a=fmtp:92 av=2\r\n
In the above example string, a=fmtp:111 can appear anywhere in the string.
We have to get the string between a=fmtp:111 and the next first appearance of \r\n which is av=1 in our case
Now we have to append ;stereo=1;sprop-stereo=1 to av=1 and append back to the original string.
The final output should be
a=fmtp:93 av=2\r\n
a=fmtp:111 av=1;stereo=1;sprop-stereo=1\r\n
a=fmtp:92 av=2\r\n
Is it possible to achieve the above chunk of logic with Replace with Regex pattern?
You can use
NSError *error = nil;
NSString *fmtpAudio = #"^a=fmtp:111 .*";
NSString *stereoString = #"$0;stereo=1;sprop-stereo=1";
NSString *myText = #"a=fmtp:93 av=2\r\na=fmtp:111 av=1\r\na=fmtp:92 av=2";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:fmtpAudio options:NSRegularExpressionAnchorsMatchLines error:&error];
NSString *modifiedString = [regex stringByReplacingMatchesInString:myText options:0 range:NSMakeRange(0, [myText length]) withTemplate: stereoString];
NSLog(#"%#", modifiedString);
Output:
a=fmtp:93 av=2
a=fmtp:111 av=1;stereo=1;sprop-stereo=1
a=fmtp:92 av=2
See the regex demo.
Details
^ - start of a line (^ starts matching line start positions due to the options:NSRegularExpressionAnchorsMatchLines option)
a=fmtp:111 - a literal string
.* - any zero or more chars other than line break chars as many as possible.
The $0 in the replacement pattern is the backreference to the whole match value.

Use regular expression to find and replace the string from Textfield in NSString

I would like to use regular expression to find and replace the string. In my scenario {3} and {2} are UITextField tag values. Based on the tag value, I would like to replace the respective textfield values and calculate the string value using NSExpression.
Sample Input String :
NSString *cumputedValue = #"{3}*0.42/({2}/100)^2";
Note: The textFields are created dynamically based on JSON response.
I got the answer for this question. Here the computedString contains the value as "{3}*0.42/({2}/100)^2".
- (NSString *)autoCalculationField: (NSString *)computedString {
NSString *computedStringFormula = [NSString stringWithFormat:#"%#",computedString];
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"\\{(\\d+)\\}"
options:0
error:nil];
NSArray *matches = [regex matchesInString:computedStringFormula
options:0
range:NSMakeRange(0, computedStringFormula.length)];
NSString *expressionStr = computedStringFormula;
for (NSTextCheckingResult *r in matches)
{
NSRange numberRange = [r rangeAtIndex:1];
NSString *newString = [NSString stringWithFormat:#"%.2f",[self getInputFieldValue:[computedStringFormula substringWithRange:numberRange]]];
expressionStr = [expressionStr stringByReplacingOccurrencesOfString:[NSString stringWithFormat:#"{%#}",[computedStringFormula substringWithRange:numberRange]] withString:newString];
}
NSExpression *expression = [NSExpression expressionWithFormat:expressionStr];
return [expression expressionValueWithObject:nil context:nil];
}
- (float)getInputFieldValue: (NSString *)tagValue {
UITextField *tempTextFd = (UITextField *)[self.view viewWithTag:[tagValue intValue]];
return [tempTextFd.text floatValue];
}
You could save the textField tags in a NSDictionary with the value that they represent.
After that use stringByReplacingOccurrencesOfString to replace the values that you wish to.
Something like this:
for (NSString *key in dict) {
cumputedValue = [cumputedValue stringByReplacingOccurrencesOfString:[NSString stringWithFormat:#"{#%}", key] withString:[NSString stringWithFormat:#"%#", dict objectForKey:#key]];
}
This way you can have the values replaced

How do I get the substring between braces?

I have a string as this.
NSString *myString = #"{53} balloons";
How do I get the substring 53 ?
NSString *myString = #"{53} balloons";
NSRange start = [myString rangeOfString:#"{"];
NSRange end = [myString rangeOfString:#"}"];
if (start.location != NSNotFound && end.location != NSNotFound && end.location > start.location) {
NSString *betweenBraces = [myString substringWithRange:NSMakeRange(start.location+1, end.location-(start.location+1))];
}
edit: Added range check, thx to Keab42 - good point.
Here is what I did.
NSString *myString = #"{53} balloons";
NSCharacterSet *delimiters = [NSCharacterSet characterSetWithCharactersInString:#"{}"];
NSArray *splitString = [myString componentsSeparatedByCharactersInSet:delimiters];
NSString *substring = [splitString objectAtIndex:1];
the substring is 53.
For Swift 4.2:
if let r1 = string.range(of: "{")?.upperBound,
let r2 = string.range(of: "}")?.lowerBound {
print (String(string[r1..<r2]))
}
You can use a regular expression to get the number between the braces. It might seem a bit complicated but the plus side is that it will find multiple numbers and the position of the number doesn't matter.
Swift 4.2:
let searchText = "{53} balloons {12} clowns {123} sparklers"
let regex = try NSRegularExpression(pattern: "\\{(\\d+)\\}", options: [])
let matches = regex.matches(in: searchText, options: [], range: NSRange(searchText.startIndex..., in: searchText))
matches.compactMap { Range($0.range(at: 1), in: searchText) }
.forEach { print("Number: \(searchText[$0])") }
Objective-C:
NSString *searchText = #"{53} balloons {12} clowns {123} sparklers";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"\\{(\\d+)\\}"
options:0
error:nil];
NSArray *matches = [regex matchesInString:searchText
options:0
range:NSMakeRange(0, searchText.length)];
for (NSTextCheckingResult *r in matches)
{
NSRange numberRange = [r rangeAtIndex:1];
NSLog(#"Number: %#", [searchText substringWithRange:numberRange]);
}
This will print out:
Number: 53
Number: 12
Number: 123
Try this code.
NSString *myString = #"{53} balloons";
NSString *value = [myString substringWithRange:NSMakeRange(1,2)];
For Swift 2.1 :-
var start = strData?.rangeOfString("{")
var end = strData?.rangeOfString("}")
if (start!.location != NSNotFound && end!.location != NSNotFound && end!.location > start!.location) {
var betweenBraces = strData?.substringWithRange(NSMakeRange(start!.location + 1, end!.location-(start!.location + 1)))
print(betweenBraces)
}
I guess, your a looking for the NSScanner class, at least if you are addressing a general case. Have a look in Apples documentation.
Search the location for "{" and "}".
Take substring between those index.
Checked with any number of data:
NSString *str = #"{53} balloons";
NSArray* strary = [str componentsSeparatedByString: #"}"];
NSString* str1 = [strary objectAtIndex: 0];
NSString *str2 = [str1 stringByReplacingOccurrencesOfString:#"{" withString:#""];
NSLog(#"number = %#",str2);
Another method is
NSString *tmpStr = #"{53} balloons";
NSRange r1 = [tmpStr rangeOfString:#"{"];
NSRange r2 = [tmpStr rangeOfString:#"}"];
NSRange rSub = NSMakeRange(r1.location + r1.length, r2.location - r1.location - r1.length);
NSString *subString = [tmpStr substringWithRange:rSub];
If you don't know how many digits there will be, but you know it will always be enclosed with curly braces try this:
NSString *myString = #"{53} balloons";
NSRange startRange = [myString rangeOfString:#"{"];
NSRange endRange = [myString rangeOfString:#"}"];
if (startRange.location != NSNotFound && endRange.location != NSNotFound && endRange.location > startRange.location) {
NSString *value = [myString substringWithRange:NSMakeRange(startRange.location,endRange.ocation - startRange.location)];
}
There's probably a more efficient way to do it though.

Finding first letter in NSString and counting backwards

I'm new to IOS, and was looking for some guidance.
I have a long NSString that I'm parsing out. The beginning may have a few characters of garbage (can be any non-letter character) then 11 digits or spaces, then a single letter (A-Z). I need to get the location of the letter, and get the substring that is 11 characters behind the letter to 1 character behind the letter.
Can anyone give me some guidance on how to do that?
Example: '!!2553072 C'
and I want : '53072 '
You can accomplish this with the regex pattern: (.{11})\b[A-Z]\b
The (.{11}) will grab any 11 characters and the \b[A-Z]\b will look for a single character on a word boundary, meaning it will be surrounded by spaces or at the end of the string. If characters can follow the C in your example then remove the last \b. This can be accomplished in Objective-C like so:
NSError *error;
NSString *example = #"!!2553072 C";
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:#"(.{11})\\b[A-Z]\\b"
options:NSRegularExpressionCaseInsensitive
error:&error];
if(!regex)
{
//handle error
}
NSTextCheckingResult *match = [regex firstMatchInString:example
options:0
range:NSMakeRange(0, [example length])];
if(match)
{
NSLog(#"match: %#", [example substringWithRange:[match rangeAtIndex:1]]);
}
There may be a more elegant way to do this involving regular expressions or some Objective-C wizardry, but here's a straightforward solution (personally tested).
-(NSString *)getStringContent:(NSString *)input
{
NSString *substr = nil;
NSRange singleLetter = [input rangeOfCharacterFromSet:[NSCharacterSet letterCharacterSet]];
if(singleLetter.location != NSNotFound)
{
NSInteger startIndex = singleLetter.location - 11;
NSRange substringRange = NSMakeRange(start, 11);
substr = [tester substringWithRange:substringRange];
}
return substr;
}
You can use NSCharacterSets to split up the string, then take the first remaining component (consisting of your garbage and digits) and get a substring of that. For example (not compiled, not tested):
- (NSString *)parseString:(NSString *)myString {
NSCharacterSet *letters = [NSCharacterSet letterCharacterSet];
NSArray *components = [myString componentsSeparatedByCharactersInSet:letters];
assert(components.count > 0);
NSString *prefix = components[0]; // assuming relatively new Xcode
return [prefix substringFromIndex:(prefix.length - 11)];
}
//to get rid of all non-Digits in a NSString
NSString *customerphone = CustomerPhone.text;
int phonelength = [customerphone length];
NSRange customersearchRange = NSMakeRange(0, phonelength);
for (int i =0; i < phonelength;i++)
{
const unichar c = [customerphone characterAtIndex:i];
NSString* onechar = [NSString stringWithCharacters:&c length:1];
if(!isdigit(c))
{
customerphone = [customerphone stringByReplacingOccurrencesOfString:onechar withString:#"*" options:0 range:customersearchRange];
}
}
NSString *PhoneAllNumbers = [customerphone stringByReplacingOccurrencesOfString:#"*" withString:#"" options:0 range:customersearchRange];

How can I extract a URL from a sentence that is in a NSString?

What I'm trying to accomplish is as follows. I have a NSString with a sentence that has a URL within the sentience. I'm needing to be able to grab the URL that is presented within any sentence that is within a NSString so for example:
Let's say I had this NSString
NSString *someString = #"This is a sample of a http://example.com/efg.php?EFAei687e3EsA sentence with a URL within it.";
I need to be able to extract http://example.com/efg.php?EFAei687e3EsA from within that NSString. This NSString isn't static and will be changing structure and the url will not necessarily be in the same spot of the sentence. I've tried to look into the three20 code but it makes no sense to me. How else can this be done?
Use an NSDataDetector:
NSString *string = #"This is a sample of a http://example.com/efg.php?EFAei687e3EsA sentence with a URL within it.";
NSDataDetector *linkDetector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:nil];
NSArray *matches = [linkDetector matchesInString:string options:0 range:NSMakeRange(0, [string length])];
for (NSTextCheckingResult *match in matches) {
if ([match resultType] == NSTextCheckingTypeLink) {
NSURL *url = [match URL];
NSLog(#"found URL: %#", url);
}
}
This way you don't have to rely on an unreliable regular expression, and as Apple upgrades their link detection code, you get those improvements for free.
Edit: I'm going to go out on a limb here and say you should probably use NSDataDetector as Dave mentions. Far less prone to error than regular expressions.
Take a look at regular expressions. You can construct a simple one to extract the URL using the NSRegularExpression class, or find one online that you can use. For a tutorial on using the class, see here.
The code you want essentially looks like this (using John Gruber's super URL regex):
NSRegularExpression *expression = [NSRegularExpression regularExpressionWithPattern:#"(?i)\\b((?:[a-z][\\w-]+:(?:/{1,3}|[a-z0-9%])|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,4}/)(?:[^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(?:\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]{};:'\".,<>?«»“”‘’]))" options:NSRegularExpressionCaseInsensitive error:NULL];
NSString *someString = #"This is a sample of a http://example.com/efg.php?EFAei687e3EsA sentence with a URL within it.";
NSString *match = [someString substringWithRange:[expression rangeOfFirstMatchInString:someString options:NSMatchingCompleted range:NSMakeRange(0, [someString length])]];
NSLog(#"%#", match); // Correctly prints 'http://example.com/efg.php?EFAei687e3EsA'
That will extract the first URL in any string (of course, this does no error checking, so if the string really doesn't contain any URL's it won't work, but take a look at the NSRegularExpression class to see how to get around it.
Use Like This:
NSError *error = nil;
NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink
error:&error];
[detector enumerateMatchesInString:someString
options:0
range:NSMakeRange(0, someString.length)
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop)
{
if (result.resultType == NSTextCheckingTypeLink)
{
NSString *str = [NSString stringWithFormat:#"%#",result.URL];
NSLOG(%#,str);
}
}];
This will Output the all links in your someString one by one
Swift 2 :
let input = "This is a test with the URL https://www.hackingwithswift.com to be detected."
let detector = try! NSDataDetector(types: NSTextCheckingType.Link.rawValue)
let matches = detector.matchesInString(input, options: [], range: NSMakeRange(0, input.characters.count))
for match in matches {
let url = (input as NSString).substringWithRange(match.range)
print(url)
}
Source
use this:
NSURL *url;
NSArray *listItems = [someString componentsSeparatedByString:#" "];
for(int i=0;i<[listItems count];i++)
{
NSString *str=[listItems objectAtIndex:i];
if ([str rangeOfString:#"http://"].location == NSNotFound)
NSLog(#"Not url");
else
url=[NSURL URLWithString:str];
}
you need two things:
A category that adds regex to NSString (i.e. RegexKit)
Matching Regex for URLS.
regards,
Funny you mention three20, that was the first place I was going to go look for the answer. Here's the method from three20:
- (void)parseURLs:(NSString*)string {
NSInteger index = 0;
while (index < string.length) {
NSRange searchRange = NSMakeRange(index, string.length - index);
NSRange startRange = [string rangeOfString:#"http://" options:NSCaseInsensitiveSearch
range:searchRange];
if (startRange.location == NSNotFound) {
NSString* text = [string substringWithRange:searchRange];
TTStyledTextNode* node = [[[TTStyledTextNode alloc] initWithText:text] autorelease];
[self addNode:node];
break;
} else {
NSRange beforeRange = NSMakeRange(searchRange.location, startRange.location - searchRange.location);
if (beforeRange.length) {
NSString* text = [string substringWithRange:beforeRange];
TTStyledTextNode* node = [[[TTStyledTextNode alloc] initWithText:text] autorelease];
[self addNode:node];
}
NSRange searchRange = NSMakeRange(startRange.location, string.length - startRange.location);
NSRange endRange = [string rangeOfString:#" " options:NSCaseInsensitiveSearch
range:searchRange];
if (endRange.location == NSNotFound) {
NSString* URL = [string substringWithRange:searchRange];
TTStyledLinkNode* node = [[[TTStyledLinkNode alloc] initWithText:URL] autorelease];
node.URL = URL;
[self addNode:node];
break;
} else {
NSRange URLRange = NSMakeRange(startRange.location,
endRange.location - startRange.location);
NSString* URL = [string substringWithRange:URLRange];
TTStyledLinkNode* node = [[[TTStyledLinkNode alloc] initWithText:URL] autorelease];
node.URL = URL;
[self addNode:node];
index = endRange.location;
}
}
}
}
Every time it does [self addNode:node]; after the first if part, it's adding a found URL. This should get you started! Hope this helps. :)
Using Swift 2.2 - NSDataDetector
let string = "here is the link www.google.com"
let types: NSTextCheckingType = [ .Link]
let detector = try? NSDataDetector(types: types.rawValue)
detector?.enumerateMatchesInString(string, options: [], range: NSMakeRange(0, (string as NSString).length)) { (result, flags, _) in
if(result?.URL != nil){
print(result?.URL)
}
}
Swift 4.x
Xcode 12.x
let string = "This is a test with the URL https://www.hackingwithswift.com to be detected. www.example.com"
let types: NSTextCheckingResult.CheckingType = [ .link]
let detector = try? NSDataDetector(types: types.rawValue)
detector?.enumerateMatches(in: string, options: [], range: NSMakeRange(0, (string as NSString).length)) { (result, flags, _) in
if(result?.url != nil){
print(result?.url)
}
}

Resources