zoukankan      html  css  js  c++  java
  • 正则表达式

    知道这强大的玩意很久了,一直没用到就没看,趁目前学习 Java 中顺便学习之 …

    初识

    正则表达式是一个用于匹配字符串的模版,提供 查找分割提取替换 等操作。

    预定义的规则

    Greedy数量词规则

    其中,? 可以理解为非贪婪模式,只匹配第一次出现的地方。

    功能与应用:实质是匹配

    [1]. 匹配  [2]. 切割  [3]. 替换 [4]. 获取

    下面重点说明下:获取

    Pattern 类和 Matcher 类用于支持正则表达式,Pattern 对象(正则对象)是正则表达式编译后在内存中的表示形式,Matcher 对象(匹配器)保存执行匹配所涉及的状态,多个 Matcher 对象可以共享一个 Pattern 对象。 

    • 合法字符 和 特殊字符:*≥0,+≥1,0≤?≤1
    • 通配符:预定义字符 和 边界匹配符;
    • 方括号表达式 和 圆括号表达式:
    • 数量表示符:默认 Greedy 模式
     Pattern pat = Pattern.comlile("a*b");
     Matcher mat = pat.matcher("b");
     boolean res1 = mat.matches();
     boolean res2 = Pattern.matches("a*b", "b");
     // res1 = res2。 另外可以利用 String 类的 matches()方法
     boolean res = 目标字符串.matches("正则表达式");

    其中,Pattern 不可变类,并发线程安全;Matcher 类的实例方法 find() 和 group() 可以从目标字符串中依次取出特定子串,start() 和 end() 确定子串的起始位置。

    常用正则表达式

    中文:@"^[u4e00-u9fa5]+$"
    英文:@"^[a-zA-Z]+$"
    数字:@"^[0-9]+$"
    邮箱:@"^[a-zA-Z0-9_+.-]+@([a-zA-Z0-9_-])+((.w{1,4}){1,3})$"
    手机号:@"^1[3,4,5,7,8]d{9}$"
    特殊字符:键盘上可见的所有非字母数字的符号@"^((?=[x21-x7e]+)[^A-Za-z0-9])$" 
           或 枚举"[`~!@#$%^&*()+=|{}':;',\[\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]"
    数字字母、特殊字符等:@"^[x21-x7e]+$"     
    

    根据手机号判断运营商

    移动 ^134[0-8]d{7}$|^(?:13[5-9]|14[78]|15[0-27-9]|165|17[28]|170[356]|18[2-478]|198)d{7,8}$
    联通 ^(?:13[0-2]|14[56]|15[56]|16[67]|176|167|170[47-9]|17[156]|18[56])d{7,8}|$
    电信 ^(?:133|1349|149|153|162|170[0-2]|173|1740[0-5]|177|18[019]|19[0139])d{6,8}$
    

    注:目前 2020.01月 版本,需及时更新

    常用场景总结

    // 将多个连续空格替换成一个
    Regex.Replace(str, "\s+", " ");
    

    最近项目上遇到问题,归类相似的SQL语句,采用正则方式,相关表达式总结如下:(待优化)

    // 表名
    public const string REG_TabName = @"s*(from|join)s+([[?#?w+-?]?.?]+)"; 
    // select...from之间的部分, 包括(select和from)
    public const string REG_SelectFrom1 = @"(^select.*?[s]*from)"; //ok
    // select...from之间的部分, 不包括(select和from)
    public const string REG_SelectFrom2 = @"(?<=^select)(.*?[s]*)(?=from)"; 
    // 匹配select top 的数字的后面部分
    public const string Reg_Top_Post = @"^(select top)s+(?d+)?s+(.+)";
    
    //INSERT INTO 表名称 VALUES (值1, 值2,....)
    //INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....)
    public const string REG_Insert = @"s*(inserts+intos+([[?#?w+-?]?.?]+))"; 
    
    //UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
    /// update xxx set...
    public const string REG_Update1 = @"s*(updates+([[?#?w+-?]?.?]+))"; //略有问题
    // update...set之间的部分, 不包括(update和set)
    public const string REG_Update2 = @"(?<=^update)(.*?[s]*)(?=set)"; 
    
    //DELETE FROM 表名称 WHERE 列名称 = 值
    public const string REG_Delete = @"(^delete.*?[s]*from)"; //问题比较大	
    

    同时推荐一个SQL解析利器:Druid - SqlParser - github;待学习!

    扩展

    正则匹配时,可以采用 静态方法Regex.Match 或 实例方法reg.Match,但是在大量重复调用同一正则表达式时,可能会存在性能问题(时间、内存)。

    Regex.CompileToAssembly

    // 摘要: 将一个或多个指定的 System.Text.RegularExpressions.Regex 对象编译为命名程序集
    // regexinfos:描述要编译的正则表达式的数组
    // assemblyname:程序集的文件名。
    public static void CompileToAssembly(RegexCompilationInfo[] regexinfos, AssemblyName assemblyname);
    

    方法使用信息参见:Regex.CompileToAssembly正则表达式的最佳实践

  • 相关阅读:
    Linux tmux 工具
    HTML 注释
    HTML 引用
    HTML 格式化
    /etc/services
    Linux ss 命令
    Python cookielib 模块
    爬取需要登录的页面
    hasattr() 、getattr() 、setattr()
    爬取文本
  • 原文地址:https://www.cnblogs.com/wjcx-sqh/p/5929899.html
Copyright © 2011-2022 走看看