正则表达式

知道这强大的玩意很久了,一直没用到就没看,趁目前学习 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*(insert\s+into\s+([\[?#?\w+-?\]?\.?]+))"; 

//UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
/// update xxx set...
public const string REG_Update1 = @"\s*(update\s+([\[?#?\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正则表达式的最佳实践

 

posted @ 2016-06-01 23:29  万箭穿心,习惯就好。  阅读(240)  评论(0编辑  收藏  举报