swift中的t正则表达式 正则表达式是对字符串操作的一种逻辑公式,用事先定义好的一些特定字符、及这些特定字符的组合,组成一个”规则字符串”,这个”规则字符串”用来表达对字符串的一种过滤逻辑。
正则表达式的用处: 判断给定的字符串是否符合某一种规则(专门用于操作字符串) 电话号码,电子邮箱,URL… 可以直接百度别人写好的正则 别人真的写好了,而且测试过了,我们可以直接用 要写出没有漏洞正则判断,需要大量的测试,通常最终结果非常负责 过滤筛选字符串,网络爬虫 替换文字,QQ聊天,图文混排
语法规则 1> 集合
1
2
3
4
5
6
[xyz ]       字符集合(x/y或z )
    [a-z ]       字符范围
    [a-zA-Z ]
    [^xyz ]      负值字符集合 (任何字符 , 除了xyz)
    [^a-z ]      负值字符范围
    [a-d ][m-p ]  并集(a到d  或 m到p)
 
2> 常用元字符
1
2
3
4
5
6
7
.           匹配除换行符以外的任意字符
\w           匹配字母或数字或下划线或汉字 [a-zA-Z_0-9]
\s           匹配任意的空白符(空格、TAB\t 、回车\r  \n )
\d           匹配数字 [0-9]
^           匹配字符串的开始
$           匹配字符串的结束
\b           匹配单词的开始或结束
 
2> 常用反义符
1
2
3
4
5
6
\W           匹配任意不是字母,数字,下划线,汉字的字符[^\w] 
  \S           匹配任意不是空白符的字符 [^\s] 
  \D           匹配任意非数字的字符[^0 -9 ]
  \B           匹配不是单词开头或结束的位置
  [^x]        匹配除了x以外的任意字符
  [^aeiou]    匹配除了aeiou这几个字母以外的任意字符
 
4> 常用限定符
1
2
3
4
5
6
*           重复零次或更多次
+           重复一次或更多次
?           重复零次或一次
{n }         重复n 次
{n ,}        重复n 次或更多次
{n ,m}       重复n 到m次,
 
5> 贪婪和懒惰
1
2
3
4
5
*?          重复任意次,但尽可能少重复
*+          重复1 次或更多次,但尽可能少重复
??          重复0 次或1 次,但尽可能少重复
{n ,m}?      重复n 到m次,但尽可能少重复
{n ,}?       重复n 次以上,但尽可能少重复
 
使用过程 1、创建规则 2、创建正则表达式对象 3、开始匹配
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private  func  check (str: String)   {
       
       do  {
           
           let  pattern = "[1-9][0-9]{4,14}" 
           
           let  regex = try  NSRegularExpression (pattern: pattern, options: NSRegularExpressionOptions .CaseInsensitive )
           
           let  res = regex.matchesInString(str, options: NSMatchingOptions (rawValue: 0 ), range: NSMakeRange (0 , str.characters.count ))
           
           for  checkingRes in  res {
               print ((str as  NSString ).substringWithRange(checkingRes.range))
           }
       }
       catch  {
           print (error)
       }
   }
 
其他几个常用方法
1
2
3
4
5
6
7
8
9
10
11
         public  func  matchesInString (string: String, options: NSMatchingOptions, range: NSRange)   -> [NSTextCheckingResult ]
         
         
         public  func  numberOfMatchesInString (string: String, options: NSMatchingOptions, range: NSRange)   -> Int 
         
         
         public  func  firstMatchInString (string: String, options: NSMatchingOptions, range: NSRange)   -> NSTextCheckingResult ?
         
         
         public  func  rangeOfFirstMatchInString (string: String, options: NSMatchingOptions, range: NSRange)   -> NSRange 
 
使用子类来匹配日期、地址、和URL 看官网文档解释,可以知道这个NSDataDetector主要用来匹配日期、地址、和URL。在使用时指定要匹配的类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public  class  NSDataDetector  : NSRegularExpression   {
    
    
    
    */
    
    public  init (types checkingTypes: NSTextCheckingTypes ) throws 
    
    public  var  checkingTypes: NSTextCheckingTypes  { get  }
}
    public  static  var  Date : NSTextCheckingType  { get  } 
    public  static  var  Address : NSTextCheckingType  { get  } 
    public  static  var  Link : NSTextCheckingType  { get  } 
 
NSDataDetector 获取URL示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  匹配字符串中的URLS
  - parameter str: 要匹配的字符串
  */
  private  func  getUrl (str:String)   {
      
      do  {
          let  dataDetector = try  NSDataDetector (types: NSTextCheckingTypes (NSTextCheckingType .Link .rawValue))
          
          let  res = dataDetector.matchesInString(str, options: NSMatchingOptions (rawValue: 0 ), range: NSMakeRange (0 , str.characters.count ))
          
          for  checkingRes in  res {
              print ((str as  NSString ).substringWithRange(checkingRes.range))
          }
      }
      catch  {
          print (error)
      }
  }
 
“.*?” 可以满足一些基本的匹配要求 如果想同时匹配多个规则 ,可以通过 “|” 将多个规则连接起来 将字符串中文字替换为表情
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
    显示字符中的表情
    - parameter str: 匹配字符串
    */
    private func getEmoji(str:String) {
        let  strM = NSMutableAttributedString(string:  str)
        do  {
            let  pattern = "\\[.*?\\]" 
            let  regex = try  NSRegularExpression(pattern: pattern, options:  NSRegularExpressionOptions.CaseInsensitive)
            let  res  = regex.matchesInString(str, options:  NSMatchingOptions(rawValue: 0 ), range : NSMakeRange(0 , str.characters.count ))
            var count  = res .count 
            // 反向取出文字表情
            while  count  > 0  {
                let  checkingRes = res [--count ]
                let  tempStr = (str as  NSString).substringWithRange(checkingRes.range )
                // 转换字符串到表情
                if  let  emoticon  = EmoticonPackage.emoticonWithStr(tempStr) {
                    print (emoticon.chs)
                    let  attrStr = EmoticonTextAttachment.imageText(emoticon, font:  18 )
                    strM.replaceCharactersInRange(checkingRes.range , withAttributedString:  attrStr)
                }
            }
            print (strM)
            // 替换字符串,显示到label
            emoticonLabel.attributedText = strM
        }
        catch  {
            print (error)
        }
    }
 
TextKit 给URL高亮显示 主要用到三个类 NSTextStorage NSLayoutManager NSTextContainer 自定义UILabel来实现url高亮
1、定义要用到的属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
   只要textStorage中的内容发生变化, 就可以通知layoutManager重新布局
   layoutManager重新布局需要知道绘制到什么地方, 所以layoutManager就会文textContainer绘制的区域
   */
   
   
   
   private  lazy  var  textStorage = NSTextStorage ()
   
   
   
   private  lazy  var  layoutManager = NSLayoutManager ()
   
   
   private  lazy  var  textContainer = NSTextContainer ()
   override  init (frame: CGRect ) {
       super .init (frame: frame)
       setupSystem()
   }
   required  init ?(coder aDecoder: NSCoder ) {
       super .init (coder: aDecoder)
       setupSystem()
   }
   
   private  func  setupSystem () 
   {
       
       textStorage.addLayoutManager(layoutManager)
       
       layoutManager.addTextContainer(textContainer)
   }
   override  func  layoutSubviews ()   {
        super .layoutSubviews()
        
        textContainer.size = bounds.size
   }
 
2、重写label的text属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 override  var  text : String ?
    {
    didSet {
        
        textStorage .setAttributedString (NSAttributedString(string : text!))
        
        
        textStorage .addAttribute (NSFontAttributeName, value : UIFont.systemFontOfSize(20 ), range : NSMakeRange(0 , text!.characters.count))
        
        
        self .URLRegex ()
        
        
        setNeedsDisplay ()
    }
}
 
3、匹配字符串
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  func URLRegex()
    {
        // 1 .创建一个正则表达式对象
        do {
            let  dataDetector = try  NSDataDetector(type s:  NSTextCheckingTypes(NSTextCheckingType.Link.rawValue))
            
            let  res  =  dataDetector.matchesInString(textStorage.string , options:  NSMatchingOptions(rawValue: 0 ), range : NSMakeRange(0 , textStorage.string .characters.count ))
            
            // 4 取出结果
            for  checkingRes in res 
            {
                let  str = (textStorage.string  as  NSString).substringWithRange(checkingRes.range )
                let  tempStr = NSMutableAttributedString(string:  str)
                
//                tempStr.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range : NSMakeRange(0 , str.characters.count ))
                tempStr.addAttributes([NSFontAttributeName: UIFont.systemFontOfSize(20 ), NSForegroundColorAttributeName: UIColor.redColor()], range : NSMakeRange(0 , str.characters.count ))
                
                textStorage.replaceCharactersInRange(checkingRes.range , withAttributedString:  tempStr)
            }
        }catch 
        {
            print (error)
        }
    }
 
4、重绘文字
1
2
3
4
5
6
7
8
9
10
override  func  drawTextInRect (rect: CGRect)   {
    
    
    
    第一个参数: 指定绘制的范围
    第二个参数: 指定从什么位置开始绘制
    */
    layoutManager.drawGlyphsForGlyphRange(NSMakeRange (0 , text!.characters.count ), atPoint: CGPointZero )
}
 
获取label中URL的点击
如果要获取URL的点击,那么必须获取点击的范围
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
override  func  touchesBegan (touches: Set<UITouch>, withEvent event: UIEvent?)   {
     
     let  touch = (touches as  NSSet ).anyObject()!
     let  point = touch.locationInView(touch.view)
     print (point)
     
     
     let  range = NSMakeRange (10 , 20 )
     
     selectedRange = range
     
     
     
     let  array = selectionRectsForRange(selectedTextRange!)
     
     for  selectionRect in  array {
         if  CGRectContainsPoint (selectionRect.rect, point) {
             print ("点击了URL" )
         }
     }
}
 
转自:http://www.cnblogs.com/songliquan/p/4860196.html