ios 如何在 Objective C (NSRegularExpression) 中编写正则表达式?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9276246/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to write regular expressions in Objective C (NSRegularExpression)?
提问by budidino
I have this regex working when I test it in PHP but it doesn't work in Objective C:
当我在 PHP 中测试它时,我有这个正则表达式工作,但它在目标 C 中不起作用:
(?:www\.)?((?!-)[a-zA-Z0-9-]{2,63}(?<!-))\.?((?:[a-zA-Z0-9]{2,})?(?:\.[a-zA-Z0-9]{2,})?)
I tried escaping the escape characters but that doesn't help either. Should I escape any other character?
我尝试转义转义字符,但这也无济于事。我应该转义任何其他角色吗?
This is my code in Objective C:
这是我在目标 C 中的代码:
NSMutableString *searchedString = [NSMutableString stringWithString:@"domain-name.tld.tld2"];
NSError* error = nil;
NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:@"(?:www\.)?((?!-)[a-zA-Z0-9-]{2,63}(?<!-))\.?((?:[a-zA-Z0-9]{2,})?(?:\.[a-zA-Z0-9]{2,})?)" options:0 error:&error];
NSArray* matches = [regex matchesInString:searchedString options:0 range:NSMakeRange(0, [searchedString length])];
for ( NSTextCheckingResult* match in matches )
{
NSString* matchText = [searchedString substringWithRange:[match range]];
NSLog(@"match: %@", matchText);
}
-- UPDATE --
- 更新 -
This regex returns (in PHP) the array with values "domain-name" and "tld.tld2" but in Objective C i get only one value: "domain-name.tld.tld2"
这个正则表达式返回(在 PHP 中)具有值“domain-name”和“tld.tld2”的数组,但在 Objective C 中我只得到一个值:“domain-name.tld.tld2”
-- UPDATE 2 --
-- 更新 2 --
This regex extracts 'domain name' and 'TLD' from the string:
此正则表达式从字符串中提取“域名”和“顶级域名”:
- domain.com = (domain, com)
- domain.co.uk = (domain, co.uk)
- -test-domain.co.u = (test-domain, co)
- -test-domain.co.uk- = (test-domain, co.uk)
- -test-domain.co.u-k = (test-domain, co)
- -test-domain.co-m = (test-domain)
- -test-domain-.co.uk = (test-domain)
- domain.com =(域,com)
- domain.co.uk =(域,co.uk)
- -test-domain.co.u = (test-domain, co)
- -test-domain.co.uk- = (test-domain, co.uk)
- -test-domain.co.uk = (test-domain, co)
- -test-domain.co-m =(测试域)
- -test-domain-.co.uk = (test-domain)
it takes the valid domain name (not starting or ending with '-' and between 2 and 63 characters long), and up to two parts of a TLD if the parts are valid (at least two characters long containing only letters and numbers)
它需要有效的域名(不以“-”开头或结尾,长度在 2 到 63 个字符之间),如果部分有效,则最多包含 TLD 的两个部分(至少两个字符长仅包含字母和数字)
Hope this explanation helps.
希望这个解释有帮助。
回答by zaph
A NSTextCheckingResult
has multiple items obtained by indexing into it.
ANSTextCheckingResult
具有通过索引获得的多个项目。
[match rangeAtIndex:0];
is the full match.[match rangeAtIndex:1];
(if it exists) is the first capture group match.
etc.
[match rangeAtIndex:0];
是完全匹配。[match rangeAtIndex:1];
(如果存在)是第一个捕获组匹配。
等等。
You can use something like this:
你可以使用这样的东西:
NSString *searchedString = @"domain-name.tld.tld2";
NSRange searchedRange = NSMakeRange(0, [searchedString length]);
NSString *pattern = @"(?:www\.)?((?!-)[a-zA-Z0-9-]{2,63}(?<!-))\.?((?:[a-zA-Z0-9]{2,})?(?:\.[a-zA-Z0-9]{2,})?)";
NSError *error = nil;
NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern: pattern options:0 error:&error];
NSArray* matches = [regex matchesInString:searchedString options:0 range: searchedRange];
for (NSTextCheckingResult* match in matches) {
NSString* matchText = [searchedString substringWithRange:[match range]];
NSLog(@"match: %@", matchText);
NSRange group1 = [match rangeAtIndex:1];
NSRange group2 = [match rangeAtIndex:2];
NSLog(@"group1: %@", [searchedString substringWithRange:group1]);
NSLog(@"group2: %@", [searchedString substringWithRange:group2]);
}
NSLog output:
NSLog 输出:
match: domain-name.tld.tld2
domain-name
tld.tld2
匹配: domain-name.tld.tld2
域名
tld.tld2
Do test that the match ranges are valid.
测试匹配范围是否有效。
More simply in this case:
在这种情况下更简单:
NSString *searchedString = @"domain-name.tld.tld2";
NSRange searchedRange = NSMakeRange(0, [searchedString length]);
NSString *pattern = @"(?:www\.)?((?!-)[a-zA-Z0-9-]{2,63}(?<!-))\.?((?:[a-zA-Z0-9]{2,})?(?:\.[a-zA-Z0-9]{2,})?)";
NSError *error = nil;
NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
NSTextCheckingResult *match = [regex firstMatchInString:searchedString options:0 range: searchedRange];
NSLog(@"group1: %@", [searchedString substringWithRange:[match rangeAtIndex:1]]);
NSLog(@"group2: %@", [searchedString substringWithRange:[match rangeAtIndex:2]]);
Swift 3.0:
斯威夫特 3.0:
let searchedString = "domain-name.tld.tld2"
let nsSearchedString = searchedString as NSString
let searchedRange = NSMakeRange(0, searchedString.characters.count)
let pattern = "(?:www\.)?((?!-)[a-zA-Z0-9-]{2,63}(?<!-))\.?((?:[a-zA-Z0-9]{2,})?(?:\.[a-zA-Z0-9]{2,})?)"
do {
let regex = try NSRegularExpression(pattern:pattern, options: [])
let matches = regex.matches(in:searchedString, options:[], range:searchedRange)
for match in matches {
let matchText = nsSearchedString.substring(with:match.range);
print("match: \(matchText)");
let group1 : NSRange = match.rangeAt(1)
let matchText1 = nsSearchedString.substring(with: group1)
print("matchText1: \(matchText1)")
let group2 = match.rangeAt(2)
let matchText2 = nsSearchedString.substring(with: group2)
print("matchText2: \(matchText2)")
}
} catch let error as NSError {
print(error.localizedDescription)
}
print output:
打印输出:
match: domain-name.tld.tld2
matchText1: domain-name
matchText2: tld.tld2
匹配:域名.tld.tld2
matchText1:域名
matchText2:tld.tld2
More simply in this case:
在这种情况下更简单:
do {
let regex = try NSRegularExpression(pattern:pattern, options: [])
let match = regex.firstMatch(in:searchedString, options:[], range:searchedRange)
let matchText1 = nsSearchedString.substring(with: match!.rangeAt(1))
print("matchText1: \(matchText1)")
let matchText2 = nsSearchedString.substring(with: match!.rangeAt(2))
print("matchText2: \(matchText2)")
} catch let error as NSError {
print(error.localizedDescription)
}
print output:
打印输出:
matchText1: domain-name
matchText2: tld.tld2
matchText1:域名
matchText2:tld.tld2
回答by hwaxxer
According to Apple's documentation, these characters must be quoted (using \) to be treated as literals:
根据Apple 的文档,这些字符必须被引用(使用 \)才能被视为文字:
* ? + [ ( ) { } ^ $ | \ . /
It would also help if you could explain what you are trying to achieve. Do you have any test fixtures?
如果您能解释您要实现的目标,这也会有所帮助。你有任何测试夹具吗?