NSRegularexpression multiline and stack - ios

I can't find a regular expression having balanced tags, one for opening and one for closing.
Tags must enclose multi lines text; and tags are dynamic, not defined at compile time
I can't match the closing tag corresponding to the opening tag, for instance {{home}} -> {{/home}} and {{hello}} -> {{/hello}}; it match {{home}} to {{/hello}}
Any help will be greatly appreciated
Any help will be greatly appreciated
gregoire
ps : I commented non working regexp
NSString * string;
NSError* error = nil;
NSRegularExpression* regex;
NSArray* matches;
string =
#" The {{demo}}following tables describe the {{/demo}}character expressions"
" used by the regular expression to match patterns within "
" a string,{{home}} the pattern operators that specify how many"
" times a pattern is matched and additional matching"
" restrictions, and the last {{/home}}table specifies flags"
" that can be included in the regular ";
regex = [NSRegularExpression regularExpressionWithPattern:
#"\\{\\{demo\\}\\}"
"(.*)?"
"\\{\\{(//|/demo)\\}\\}"
options:NSRegularExpressionDotMatchesLineSeparators
error:&error];
// regex = [NSRegularExpression regularExpressionWithPattern:
// #"\\{\\{.*\\}\\}"
// "(.*)?"
// "\\{\\{(//|/.*)\\}\\}"
// options:NSRegularExpressionDotMatchesLineSeparators
// error:&error];
matches = [regex matchesInString:string
options:NSRegularExpressionDotMatchesLineSeparators
range:NSMakeRange(0, [string length])];
for ( NSTextCheckingResult* match in matches )
{
NSLog(#"### %# ###", [string substringWithRange:[match range]]);
}

You can use this pattern
\{\{([^/]*?)\}\}(.*?)\{\{(/\1|//)\}\}
------- ---- --------
| | |->matches closing tag having value same as group 1 or //
| |->content in group 2
|->matches the opening tag value and captures it in group1

Related

Regular expression for password validation - Objective C

I need a regular expression that can validate following cases,
Be 8 to 20 characters
Use at least 1 upper case letter, 1 lower case letter, and 1 number
Not repeat the same number or letter more than 3 times in a row
Not contain spaces, and may only use these characters
# # * ( ) + = { } / ? ~ ; , . - _
The closest solution I can find is
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\da-zA-Z])(?=.*[#(#*){+=}/?~;,._]).{8,20}$
But contains following issue,
Accepting space
Can't add - character
Repeating same number or letter more than 3 times in a row.
EDIT: Fixed the repeating character issues and have final expression like,
^(?!.*?(.)\1{3})(?!.* )(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?!.*[:£€&"!'[\]%^\|<>$]).{8,20}$
But its only working on online tester like [RegExr][1]
I tried following code but it generates runtime
- (BOOL)string:(NSString *)text matches:(NSString *)pattern{
NSError *error;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
NSArray *matches = [regex matchesInString:text options:0 range:NSMakeRange(0, text.length)];
return matches.count > 0;
}

Regular expression to extract text line by line

Is it possible to make a regex check line by line of the data? So if I have the text as:
#EXTINF:-1 tvg-name="seedocs" tvg-logo="RT",RT
#http://odna.octoshape.net/f3f5m2v4/cds/ch5_320p/chunklist.m3u8
#http://odna.octoshape.net/f3f5m2v4/cds/ch5_720p/chunklist.m3u8
http://rt.ashttp14.visionip.tv/live/rt-global-live-HD/playlist.m3u8
#EXTINF:-1 tvg-name="hsn" tvg-logo="hsn",HSN TV
rtsp://hsn.mpl.miisolutions.net:1935/hsn-live01/_definst_/mp4:420p500kB31
I want to remove all the text start from: #http:....
So that i have used the code as below:
To get the match data:
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"((#EXTINF.*\r\n)(.*))+(http|https)://((\\w)*|([0-9]*)|([-|_])*\r\n)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+" options:NSRegularExpressionCaseInsensitive error:&error];
To Remove text start from #http...:
NSRegularExpression *regexName = [NSRegularExpression regularExpressionWithPattern:#"#.*$" options:NSRegularExpressionCaseInsensitive error:&error];
This will give the output as below in the log:
#EXTINF:-1 tvg-name="seedocs" tvg-logo="RT",RT
which mean, i could not retrieve the value of:
http://rt.ashttp14.visionip.tv/live/rt-global-live-HD/playlist.m3u8
my output should be something like this:
#EXTINF:-1 tvg-name="seedocs" tvg-logo="RT",RT
http://rt.ashttp14.visionip.tv/live/rt-global-live-HD/playlist.m3u8
Please somebody help me to sortout this issue.
It is possible to construct REs which match multiple lines, but doing so can be a challenge - both to you and the RE engine. You are usually better off matching single lines; for example you could match lines starting with #http, include the line terminator, and replace each such match with nothing.
However if you are doing line-by-line processing you might be even better off using componentsSeparatedByString: to first break your input into lines, and then processing each line - say by dropping those which start with #http (use hasPrefix:).
HTH
Checkout the following code to do this: I want to remove all the text start from: #http:....
NSMutableString *finalString = string.mutableCopy;
[string enumerateLinesUsingBlock:^(NSString *line, BOOL *stop) {
if ([line hasPrefix:#"#http"]) {
[finalString replaceOccurrencesOfString:line withString:#"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, finalString.length)];
}
}];

How to replace strings using regex in objective C?

I have a string that sometimes contains strings like: #"[id123123|Some Name]"
What I have to do, is to simply replace it to "Some Name"
For example I have string: Some text lalala blabla [id123|Some Name] bla bla bla
And I need to get: Some text lalala blabla Some Name bla bla bla
The question is how to? My mind tells me that I can do this with NSRegularExpression
Look into stringByReplacingOccurrencesOfString:withString:options:range:. The options: allow the search string to be a regular expression pattern.
Not an Objective C person, but judging from this previous SO post, you could use a regex like so:
NSString *regexToReplaceRawLinks = #"\\[.+?\\|(.+?)\\]";
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexToReplaceRawLinks
options:NSRegularExpressionCaseInsensitive
error:&error];
NSString *string = #"[id123|Some Name]";
NSString *modifiedString = [regex stringByReplacingMatchesInString:string
options:0
range:NSMakeRange(0, [string length])
withTemplate:#"$1"];
This should match the string you are using and place the name in a group. You then replace the entire string [id123|Some Name] with Some Name.
Regex101
(\[[^|]+|([^\]]+]))
Description
\[ matches the character [ literally
[^|]+ match a single character not present in the list below
Quantifier: + Between one and unlimited times, as many times as possible, giving back as needed [greedy]
| the literal character |
\| matches the character | literally
1st Capturing group ([^\]]+])
[^\]]+ match a single character not present in the list below
Quantifier: + Between one and unlimited times, as many times as possible, giving back as needed [greedy]
\] matches the character ] literally
] matches the character ] literally
In capture group 1 is the thing you want to replace with what is in capture group 2. enjoy.

iOS - NSString regex match

I have a string for example:
NSString *str = #"Strängnäs"
Then I use a method for replace scandinavian letters with *, so it would be:
NSString *strReplaced = #"Str*ngn*s"
I need a function to match str with strReplaced. In other words, the * should be treated as any character ( * should match with any character).
How can I achieve this?
Strängnäs should be equal to Str*ngn*s
EDIT:
Maybe I wasn't clear enough. I want * to be treated as any character. So when doing [#"Strängnäs" isEqualToString:#"Str*ngn*s"] it should return YES
I think the following regex pattern will match all non-ASCII text considering that Scandinavian letters are not ASCII:
[^ -~]
Treat each line separately to avoid matching the newline character and replace the matches with *.
Demo: https://regex101.com/r/dI6zN5/1
Edit:
Here's an optimized pattern based on the above one:
[^\000-~]
Demo: https://regex101.com/r/lO0bE9/1
Edit 1: As per your comment, you need a UDF (User defined function) that:
takes in the Scandinavian string
converts all of its Scandinavian letters to *
takes in the string with the asterisks
compares the two strings
return True if the two strings match, else false.
You can then use the UDF like CompareString(ScanStr,AsteriskStr).
I have created a code example using the regex posted by JLILI Amen
Code
NSString *string = #"Strängnäs";
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"[^ -~]" options:NSRegularExpressionCaseInsensitive error:&error];
NSString *modifiedString = [regex stringByReplacingMatchesInString:string options:0 range:NSMakeRange(0, [string length]) withTemplate:#"*"];
NSLog(#"%#", modifiedString);
Output
Str*ngn*s
Not sure exactly what you are after, but maybe this will help.
The regular expression pattern which matches anything is. (dot), so you can create a pattern from your strReplaced by replacing the *'s with .'s:
NSString *pattern = [strReplaced stringByReplacingOccurencesOfString:#"*" withString:"."];
Now using NSRegularExpression you can construct a regular expression from pattern and then see if str matches it - see the documentation for the required methods.

Regex to determine if path is root directory

I am in iOS but pretty much any language will translate.
I am trying to write a regular expression to match a root directory:
ie:
First/ should match
First/file.txt should not match
First/next should not match
First/next/file.txt should not match
So I think the logic should be start at beginning of line match any character except "/" then match "/" only once and that one time should be at the end of the string.
I have:
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"[^\\/]*\\/$" options:NSRegularExpressionCaseInsensitive error:&error];
NSUInteger matches = [regex numberOfMatchesInString:info.name options:NSRegularExpressionCaseInsensitive range:NSMakeRange(0, [info.name length])];
if (matches > 0) {
NSLog(#"match");
} else {
NSLog(#"not a match");
}
But its not matching like it should.
Thinking
[^\\/]*
will match all characters that are not "/"
Then
\\/$
will match a "/" that is at the end of the string.
Where am I going wrong?
The regular expression would be:
^[^/]*/$
This ensures the string ends with a slash and it can contain 0 or more non-slash characters before it.
Another solution (without regular expression) would be this:
NSString *name = ... // some path
if (name.length && [name rangeOfString:#"/"].location == name.length - 1) {
// root directory
}

Resources