2012-02-14 44 views
44

我有這樣的正則表達式時,我在PHP測試工作,但它不能在目標C的工作:如何在Objective C(NSRegularExpression)中編寫正則表達式?

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

我試圖逃避轉義字符,但是這並沒有幫助。我應該逃避任何其他角色嗎?

這是我的目標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 -

此正則表達式返回(在PHP)與值 「域名」 和 「tld.tld2」 陣列但在目標C我只得到一個值:「域name.tld.tld2」

- UPDATE 2 -

此正則表達式提取「域名」和「TLD」從字符串:

  • domain.com =(域,COM)
  • domain.co.uk =(域,co.uk)
  • -test-domain.co.u =(測試域,共)
  • -test-domain.co.uk- =(測試域,co.uk)
  • -test-domain.co.uk =(測試域,共)
  • -test-domain.co- m =(test-domain)
  • -test-domain-.co.uk =(test-domain)

它採用有效的域名(不以' - '開頭或以' - '結尾,長度在2到63個字符之間),以及最多兩個TLD部分,如果這些部分有效(至少兩個字符只包含字母和數字)

希望這個解釋有幫助。

+0

電子郵件驗證? – Hiren 2012-02-14 11:47:07

+0

也許這有幫助嗎? http://stackoverflow.com/questions/5478170/regular-expression-in-ios – dom 2012-02-14 11:49:38

+2

我認爲恐諾問如何將現有的正則表達式轉換爲ObjectiveC代碼。正則表達式的作用並不重要。 – 2012-02-14 11:56:05

回答

70

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]); 
} 

的NSLog輸出:

匹配:域name.tld.tld2
域名
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]]); 

夫特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) 
} 

打印輸出:

匹配:域name.tld.tld2
matchText1:d omain名
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) 
} 

打印輸出:

matchText1:域名
matchText2:tld.tld2

+0

我上面的代碼目前顯示所有匹配的結果(完全匹配,域名,頂級域名),並且在我在線測試該正則表達式時有效,但在Objective C中測試時僅返回第一個值(完全匹配)。 – budidino 2012-02-14 12:35:19

+0

看起來像我有一個「NSMutableString stringWithString」部分的問題,因爲正則表達式在線不匹配相同的東西VS Objective C – budidino 2012-02-14 12:36:31

+1

對不起,你是對的。看起來我不明白如何正確獲得結果。我是我的核心Web開發人員,Objective C只是讓我嘗試做的所有事情至少比PHP中的要困難2倍:)再次感謝。 – budidino 2012-02-14 12:51:25

11

Apple's documentation,這些字符必須(使用\)報價將被視爲文字:

* ? + [ () { }^$ | \ ./

這也將有助於如果你能解釋一下你正在努力實現的目標。你有任何測試夾具?

+0

在標準的正則表達式意義上?或被視爲正則表達式運算符? – 2013-02-14 14:37:57

+0

我一直在obj-c中嘗試正則表達式,但是我無法獲得'\ ['工作。有任何想法嗎? – ZuluDeltaNiner 2013-09-17 03:27:16

+10

您必須先避開反斜槓。 \\\ [ – 2013-12-04 17:00:06