如何写一个正则表达式(基础入门篇)

一、基础内容

一、常见的元字符

^:匹配字符串的开始。
$:匹配字符串的结束。

. :匹配除了换行符以外的任意字符。有点类似我们平常理解的*
\w:匹配字母、数字、下划线和汉字。wild
\s
\b
\d:digital,匹配一个数字。

\:转义符号。比如如果你想查找.这个字符,但是.本身是个元字符,程序也会把它理解为一个元字符,而不是一个普通字符。所以要想把它变成普通字符,就得写成\.

二、重复型字符

*:重复 >=0 次。
+:重复 >=1 次。
?:重复 0 或 1 次。可以这样记:?代表bool值,要么是0,要么是1。
{n}:重复n次。
{n,}:重复 >=n 次。
{n,m}:重复 n到m 次。

三、

[]:匹配被[]包含的任意一个单独的字符。比如[world],匹配w、o、r、l、d中任意一个字母。注意它并非匹配world这个单词。

():表示分组,就是把特定的一个表达式打组。

-:表示一个范围,用于有序字符。一般跟[]配合使用。比如[0-9],匹配0到9中的任意一个字符。[A-Z],匹配大写的A到Z英文字母,[a-z]匹配小写的a到z英文字母。

小练习: \(?0\d{2}[) -]?\d{8} 想要匹配一个座机号码
从左往右看:
\(表示要匹配(。然后加上?,表示(要么没有,要么只有一个。
0就是匹配0
\d表示匹配 0到9任意一个数字。加上{2}表示一共两个数字。
[) -]表示匹配)空格或者-中的任意一个。加上?表示:要么匹配)空格或者-中的任意一个,要么啥都不匹配。
\d{8}表示匹配8个数字。
结果:可以匹配到 (010)80884324、022-34432455或者022 34442323。

四、分支

上面的表达式还可以匹配到诸如:(022-34432455这样的不合法字符。因为()要成对出现才不会有问题,但是你没有指定。

所以我们要分条件来写:

  1. 只包含()
  2. 只包含-
    所以最终的表达式为:\(0\d{2}\)[- ]?\d{8}|0\d{2}[- ]?\d{8}

五、分组

(\d{1,3}\.){3}\d{1,3}是一个简单的IP地址匹配表达式。要理解这个表达式,请按下列顺序分析它:\d{1,3}匹配1到3位的数字,(\d{1,3}\.){3}匹配一到三位数字加上一个英文句号,然后整体重复3次,最后再加上一个一到三位的数字(\d{1,3})

六、反义

把对应的字母换成大写。
\W:匹配任意不是 字母、数字、下划线和汉字 的字符。
\D:匹配任意不是 数字 的字符。
\S
[^xyz]:匹配除了x、y、z以外的任意字母。

二、在iOS中的用法

  1. 使用谓词 NSPredicate

    1
    2
    3
    4
    NSString *email = @“nijino_saki@163.com”;
    NSString *regex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    BOOL isValid = [predicate evaluateWithObject:email];
  2. 使用rangOfString: option:

    1
    2
    3
    4
    5
    6
    7
    NSString *searchText = @"string";
    NSString *regex = @"(?:[^,])*\\.";
    NSRange range = [searchText rangeOfString:regex options:NSRegularExpressionSearch];

    if (range.location != NSNotFound) {
    NSLog(@"%@", [searchText substringWithRange:range]);
    }
  3. 使用正则表达式类:NSRegularExpression,可以精确拿到匹配的内容所在的位置和大小。

    1
    2
    3
    4
    5
    6
    7
    NSString *searchText = @"string";   
    NSError *error = NULL;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(?:[^,])*\\." options:NSRegularExpressionCaseInsensitive error:&error];
    NSTextCheckingResult *result = [regex firstMatchInString:searchText options:0 range:NSMakeRange(0, [searchText length])];
    if (result) {
    NSLog(@"%@\n", [searchText substringWithRange:result.range]);
    }

或者

1
2
3
4
5
6
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(?:[^,])*\\." options:kNilOptions error:NULL];

NSArray <NSTextCheckingResult *>*results = [regex matchesInString:text.string options:kNilOptions range:text.rangeOfAll];
for (NSTextCheckingResult *result in atResults) {
if (result.range.location == NSNotFound && result.range.length <= 1) continue;
}

值得一提的是假设在OC中写:

1
NSString *regex = @"1[345789]\d{9}";

会提示:Unknown escape sequence ‘\d’
需要改成:

1
NSString *regex = @"1[345789]\\d{9}";