如何在Objective C(NSRegularExpression)中编写正则表达式?

bud*_*ino 48 regex objective-c ios nsregularexpression

当我在PHP中测试时,我有这个正则表达式工作,但它在Objective C中不起作用:

(?:www\.)?((?!-)[a-zA-Z0-9-]{2,63}(?<!-))\.?((?:[a-zA-Z0-9]{2,})?(?:\.[a-zA-Z0-9]{2,})?)
Run Code Online (Sandbox Code Playgroud)

我试图逃避转义字符,但这也无济于事.我应该逃避任何其他角色吗?

这是我在Objective 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);
}
Run Code Online (Sandbox Code Playgroud)

- 更新 -

此正则表达式返回(在PHP中)具有值"domain-name"和"tld.tld2"的数组,但在Objective C中,我只获得一个值:"domain-name.tld.tld2"

- 更新2 -

此正则表达式从字符串中提取"域名"和"TLD":

  • 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 =(测试域)

它采用有效的域名(不以' - '开头或结尾,长度在2到63个字符之间),如果部分有效,则最多为TLD的两个部分(至少两个字符只包含字母和数字)

希望这个解释有所帮助

zap*_*aph 77

A NSTextCheckingResult通过索引获得多个项目.

[match rangeAtIndex:0];是完全匹配.
[match rangeAtIndex:1];(如果存在)是第一个捕获组匹配.
等等

你可以使用这样的东西:

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]);
}
Run Code Online (Sandbox Code Playgroud)

NSLog输出:

match:domain-name.tld.tld2
domain-name
tld.tld2

测试匹配范围是否有效.

在这种情况下更简单:

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]]);
Run Code Online (Sandbox Code Playgroud)

Swift 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)
}
Run Code Online (Sandbox Code Playgroud)

打印输出:

match:domain-name.tld.tld2
matchText1:domain-name
matchText2:tld.tld2

在这种情况下更简单:

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)
}
Run Code Online (Sandbox Code Playgroud)

打印输出:

matchText1:domain-name
matchText2:tld.tld2

  • 对不起,你是对的。看起来我不明白如何正确获得结果。我的核心是 Web 开发人员,Objective C 使我尝试做的所有事情至少比在 PHP 中难做 2 倍 :) 再次感谢。 (2认同)
  • 整个`NSTextCheckingResult`是一个受伤的世界,因为它确实很多并且正在用于正则表达式的过度杀戮.很明显它含有捕获基团. (2认同)

hwa*_*xer 14

根据Apple的文档,必须引用这些字符(使用\)作为文字处理:

* ? + [ ( ) { } ^ $ | \ . /
Run Code Online (Sandbox Code Playgroud)

如果你能解释你想要实现的目标,那也会有所帮助.你有测试装置吗?

  • 你必须首先逃避反斜杠.\\\ [ (11认同)