正则表达式

  正则表达式(Regular expression) 是一种通用的字符串匹配模式,我更喜欢把它说成是一种语法。

  一般用于如下操作:

  1. 用来检测目标字符串是否“包含”特定字符 -----(屏蔽字等)
  2. 用来检测目标字符串是否“匹配”特定规则 -----  (ip地址,账号密码)
  3. 用来“捕获”满足条件的语句 ---------------(协议交互,关键数据提取)
  4. 用来将匹配的字符串进行“替换” ------------ (版本号,敏感词替换成*)

常见关键字

特别字符 描述
^

1.匹配字符串开头位置

2.放在括号中表示不接受xxx字符

$ 1.匹配文本末尾
() 子表达式范围
* 0次或多次 等价于 {0,}
+ 1次或多次 等价于 {1,}
? 0次或1次 等价于 {0,1}
. 除\n以外任意单字符
[] 中括号表达式(一般是取值范围)
{} 限定符表达式(一般为次数限定)
|
{n} n是一个非负数 匹配确定n次
{n,} n是一个非负数 至少匹配n次
{n,m} n&m是一个非负数 m >= n ,至少匹配n次 至多匹配m次
?= 捕获断言前匹配的内容 (尾缀匹配)
?!x 负向捕获(尾缀匹配 很少用)
?<=x 捕获断言后匹配内容(前缀匹配)
?<!x 负向捕获 (前缀匹配 很少用)
\w 匹配字母 数字 下划线 等价于[A-Za-z0-9_]
\s 匹配任何空白字符包括空格、制表符、换行等[\f\n\r\t\v]
\S 匹配任何非空白字符

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


事例 PS (验证函数见完整版代码)

------ 账号验证 (格式匹配)------

  1. 以“大/小写字母”开头
  2. 只允许使用“大/小写字母”“阿拉伯数字”
  3. 文本长度必须在 5 - 12 之间
        /* 账号验证
        *1.以 "大/小写字母" 开头
        *2.除开头以外只能存在 “大 / 小写字母” “阿拉伯数字”
        *3.文本长度必须在5 - 12
        */
        string testStr0 = "jw328791554";
        string testStr1 = "dasd";
        string testStr2 = "1jwhjkadhksa";
        string testStr3 = "jiangweio3778913123";
        string testStr4 = "Jw32tason3";

        Regex rgx = new Regex(@"^[a-zA-Z][a-zA-Z0-9]{5,12}$"); 

        RegexMatchTest(testStr0, rgx);
        RegexMatchTest(testStr1, rgx);
        RegexMatchTest(testStr2, rgx);
        RegexMatchTest(testStr3, rgx);
        RegexMatchTest(testStr4, rgx);
View Code

----- 密码验证 (格式匹配) ------

  1. 不能为纯数字
  2. 不能为纯字母
  3. 长度必须在 6 - 20 之间
        /* 密码验证
         * 1.不能为纯数字
         * 2.不能为纯字母
         * 3.长度必须在 6 - 20
         * 
         * ?! 表示 “负向预查” 任何不匹配的字符串
         */
        string testStr5 = "3213123";
        string testStr6 = "dsadsaddsadasd";
        string testStr7 = "jwJw381";
        string testStr8 = "我的大鲵";
        string testStr9 = "01sd10";

        Regex rgx2 = new Regex(@"^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$");
        RegexMatchTest(testStr5, rgx2);
        RegexMatchTest(testStr6, rgx2);
        RegexMatchTest(testStr7, rgx2);
        RegexMatchTest(testStr8, rgx2);
        RegexMatchTest(testStr9, rgx2);
View Code

 

----- 手机号码验证 (格式匹配)-----

 

  1.  全数字
  2. 1开头的11位数字
  3. 第二位为[34578]
        /*
         * 手机号码验证
         * 1.全部为数字
         * 2.1 开头 的 11位数字
         * 3.第二位在 [34578]
         */
        string testStr10 = "15928517727";
        string testStr11 = "_110";
        Regex rgx3 = new Regex(@"1[34578]\d{9}$");

        RegexMatchTest(testStr10, rgx3);
        RegexMatchTest(testStr11, rgx3);
View Code

 

----- 是否包含中文 (格式匹配) -----

  1. 范围匹配
        /*
         * 是否包含中文
         * 1.[\x4e00 - \x9fa5]+
         */      
         string testStr12 = "jiangwei将";
        string testStr13 = "蒋伟";
        string testStr14 = "j将 _ 为";
        string testStr15 = "vvvvv";
        Regex rgx4 = new Regex(@"[\u4e00-\u9fa5]+");

        RegexMatchTest(testStr12, rgx4);
        RegexMatchTest(testStr13, rgx4);
        RegexMatchTest(testStr14, rgx4);
        RegexMatchTest(testStr15, rgx4);
View Code

 

----- 敏感词匹配 (格式匹配)-----

        /*
         * 敏感词 匹配
         * | 用于取或
         */
        string testStr16 = "蒋伟珠海妮李小满薛菡岳圆Def";
        Regex rgx5 = new Regex("(大侠们)+");
        Regex rgx6 = new Regex("(大侠们|薛菡)+");

        RegexMatchTest(testStr16, rgx5);
        RegexMatchTest(testStr16, rgx6);
View Code

 

----- 敏感词替换 (文本替换 )-----

  //敏感词 替换
        string testStr31 = "我支持香港警察,好了,你们可以打我了!<舆论暴徒,记者>";
        Regex rgx23 = new Regex(@"舆论压力|香港警察");
        Regex rgx24 = new Regex(@"记者|牛逼");
        string temp = rgx23.Replace(testStr31, "****");
        temp = rgx24.Replace(temp, "**");
        Debug.Log(temp);
View Code

 

----- 字符串过滤 (格式匹配)-----

        /*
         * 过滤字符串数组      
         */

        string[] filePaths = new string[] { "jw0.data", "jw1.data", "jw1_1.data", "jw1_44.data", "jw45", "yy45.data", "libray.txt", "jwjw213", "jwjw341_3.data","jw34.data"};
        Regex rgx7 = new Regex(@".*\.data");//过滤所有的.data文件
        //string[] temp = RegexScreen(filePaths, rgx7);
        Regex rgx8 = new Regex(@"^jw.*\.data");//过滤所有的jw*.data文件
        //string[] temp = RegexScreen(filePaths, rgx8);
        Regex rgx9 = new Regex(@"^jw[0-9]+\.data");//过滤所有jw开头接着只有数字以.data结尾的文件
        RegexScreen(filePaths, rgx9);
View Code

 

 ----- Ipv4 ip地址匹配 (格式匹配)-----

        /*
         * 1. IPv4地址匹配 
         * \d{1,3}(.\d{1,3}){3})
         * 
         * 这里仅仅是试试“捕获组”,并不是真正意义上的捕获
         * 这里的捕获更多是一种特殊形式的文本简写,列入下列表达式可以
         * 特殊匹配4个相同数字的ip地址格式,因为这里\1捕获的是1号(0号位为表达式本身)的文本数据
         * (\d{1,3,})(.\1){3}       
         */
        string testStr17 = "192.168.1.2";
        string testStr18 = "192.168.256.333";
        string testStr19 = "localhost";
        Regex rgx10 = new Regex(@"\d{1,3}(.\d{1,3}){3}");
        RegexMatchTest(testStr17, rgx10);
        RegexMatchTest(testStr18, rgx10);
        RegexMatchTest(testStr19, rgx10);
View Code

 

-----  协议长度捕获 (文本捕获) -----

   /*
         * 协议长度捕获(非捕获组 常用类型捕获 零宽度断言)
         * 1.?=x 捕获断言前匹配内容 (尾缀匹配)
         * 2.?!x 负向捕获 (很少用) (尾缀匹配)
         * 3.?<=x 捕获断言后匹配内容 (前缀匹配)
         * 4. ?<!x 负向捕获 (很少用) (前缀匹配)
         * eg0:以一定格式进行区分 如 [Length=xxx]xxxxx
        */

        string testStr20 = "product_path";
        Regex rgx12 = new Regex(@"(\w+)(?=_path)");
        RegexCatchTest(testStr20, rgx12);

        string testStr21 = "product_path,jiangwei_path";
        Regex rgx13 = new Regex(@"(\w+)(?=_path)");
        RegexCatchTest2(testStr21, rgx13);

        string testStr22 = @"[Length=17]jiangweiasdasd";
        Regex rgx14 = new Regex(@"(?<=\[Length=)(\d+)(?=\])");
        RegexCatchTest(testStr22, rgx14);


        string testStr23 = @"[Length=17]jiangweiasdasd[Length=21]dasda[lengt= 13";
        Regex rgx15 = new Regex(@"(?<=\[Length=)(\d+)(?=\])");
        RegexCatchTest2(testStr23, rgx15);
View Code

 

-----  数字截断 浮点数截断 (文本捕获) -----

        /*
         * 数字截断      
         */      

        string testStr24 = "3.1415926";
        Regex rgx16 = new Regex(@"^\d+\.\d{1,3}");
        RegexCatchTest(testStr24, rgx16);
View Code

 

----- 大小写 容差 (修正符) -----

  /*
         * 修正符
         * 以?开始的修正符
         * (?!) 表示后面所有字符开启不区分大小写模式 (暂未测试成功)
         * (?!:x) 单x不区分大小写
         * */

        string testStr25 = "Ab";
        string testStr26 = "AB";
        Regex rgx17 = new Regex("(?!:a)b");
        Regex rgx20 = new Regex("(?!:ab)");
        RegexMatchTest(testStr25, rgx17);
        RegexMatchTest(testStr26, rgx17);
        RegexMatchTest(testStr25, rgx20);
        RegexMatchTest(testStr26, rgx20);
View Code

 

----- 截断测试 2 (这个忽略掉)-----

        /*
           截断测试2
         */

        string testStr27 = "5567";
        string testStr28 = "4313145151756655";
        Regex rgx18 = new Regex("(?<!4)56(?=7)");
        Regex rgx19 = new Regex(@"(?<=4)\d+(?=7)");
        RegexCatchTest(testStr27, rgx18);
        RegexCatchTest(testStr28, rgx19);
View Code

 

----- 空白符删除 (文本替换)-----

  /*
         * 替换  (剔除所有空白字符)
         */      
        string testStr29 = "<Length=25>   dashdkasdhk<Length=24>  dasd  \r\n";
        Regex rgx21 = new Regex(@"\s");
        Debug.Log(rgx21.Replace(testStr29, ""));
View Code

 

----- 版本号替换 (文本替换) -----

 //版本号 替换 
        string testStr30 = "static public string BUILD_VERSION = 1.0; SCrore line";
        Regex rgx22 = new Regex(@"(?<=BUILD_VERSION\s?=\s?).*(?=;)");
        Debug.Log(rgx22.Replace(testStr30, "2.0"));
View Code

 

 


 

 完整版代码 

using UnityEngine;
using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;

public class JwTest : MonoBehaviour 
{

    void Start () 
    {    
        /* 账号验证
        *1.以 "大/小写字母" 开头
        *2.除开头以外只能存在 “大 / 小写字母” “阿拉伯数字”
        *3.文本长度必须在5 - 12
        */
        string testStr0 = "jw328791554";
        string testStr1 = "dasd";
        string testStr2 = "1jwhjkadhksa";
        string testStr3 = "jiangweio3778913123";
        string testStr4 = "Jw32tason3";

        Regex rgx = new Regex(@"^[a-zA-Z][a-zA-Z0-9]{5,12}$"); 

        //RegexMatchTest(testStr0, rgx);
        //RegexMatchTest(testStr1, rgx);
        //RegexMatchTest(testStr2, rgx);
        //RegexMatchTest(testStr3, rgx);
        //RegexMatchTest(testStr4, rgx);

        /* 密码验证
         * 1.不能为纯数字
         * 2.不能为纯字母
         * 3.长度必须在 6 - 20
         * 
         * ?! 表示 “负向预查” 任何不匹配的字符串
         */
        string testStr5 = "3213123";
        string testStr6 = "dsadsaddsadasd";
        string testStr7 = "jwJw381";
        string testStr8 = "我的大鲵";
        string testStr9 = "01sd10";

        Regex rgx2 = new Regex(@"^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$");
        //RegexMatchTest(testStr5, rgx2);
        //RegexMatchTest(testStr6, rgx2);
        //RegexMatchTest(testStr7, rgx2);
        //RegexMatchTest(testStr8, rgx2);
        //RegexMatchTest(testStr9, rgx2);

        /*
         * 手机号码验证
         * 1.全部为数字
         * 2.1 开头 的 11位数字
         * 3.第二位在 [34578]
         */
        string testStr10 = "15928517727";
        string testStr11 = "_110";
        Regex rgx3 = new Regex(@"1[34578]\d{9}$");

        //RegexMatchTest(testStr10, rgx3);
        //RegexMatchTest(testStr11, rgx3);

        /*
         * 是否包含中文
         * 1.[\x4e00 - \x9fa5]+
         */      
         string testStr12 = "jiangwei将";
        string testStr13 = "蒋伟";
        string testStr14 = "j将 _ 为";
        string testStr15 = "vvvvv";
        Regex rgx4 = new Regex(@"[\u4e00-\u9fa5]+");

        //RegexMatchTest(testStr12, rgx4);
        //RegexMatchTest(testStr13, rgx4);
        //RegexMatchTest(testStr14, rgx4);
        //RegexMatchTest(testStr15, rgx4);

        /*
         * 敏感词 匹配
         * | 用于取或
         */
        string testStr16 = "蒋伟珠海妮李小满薛菡岳圆Def";
        Regex rgx5 = new Regex("(大侠们)+");
        Regex rgx6 = new Regex("(大侠们|薛菡)+");

        //RegexMatchTest(testStr16, rgx5);
        //RegexMatchTest(testStr16, rgx6);

        /*
         * 过滤字符串数组      
         */

        string[] filePaths = new string[] { "jw0.data", "jw1.data", "jw1_1.data", "jw1_44.data", "jw45", "yy45.data", "libray.txt", "jwjw213", "jwjw341_3.data","jw34.data"};
        Regex rgx7 = new Regex(@".*\.data");//过滤所有的.data文件
        //string[] temp = RegexScreen(filePaths, rgx7);
        Regex rgx8 = new Regex(@"^jw.*\.data");//过滤所有的jw*.data文件
        //string[] temp = RegexScreen(filePaths, rgx8);
        Regex rgx9 = new Regex(@"^jw[0-9]+\.data");//过滤所有jw开头接着只有数字以.data结尾的文件
        RegexScreen(filePaths, rgx9);


        /*
         * 1. IPv4地址匹配 
         * \d{1,3}(.\d{1,3}){3})
         * 
         * 这里仅仅是试试“捕获组”,并不是真正意义上的捕获
         * 这里的捕获更多是一种特殊形式的文本简写,列入下列表达式可以
         * 特殊匹配4个相同数字的ip地址格式,因为这里\1捕获的是1号(0号位为表达式本身)的文本数据
         * (\d{1,3,})(.\1){3}       
         */
        string testStr17 = "192.168.1.2";
        string testStr18 = "192.168.256.333";
        string testStr19 = "localhost";
        Regex rgx10 = new Regex(@"\d{1,3}(.\d{1,3}){3}");
        RegexMatchTest(testStr17, rgx10);
        RegexMatchTest(testStr18, rgx10);
        RegexMatchTest(testStr19, rgx10);


        /*
         * 协议长度捕获(非捕获组 常用类型捕获 零宽度断言)
         * 1.?=x 捕获断言前匹配内容 (尾缀匹配)
         * 2.?!x 负向捕获 (很少用) (尾缀匹配)
         * 3.?<=x 捕获断言后匹配内容 (前缀匹配)
         * 4. ?<!x 负向捕获 (很少用) (前缀匹配)
         * eg0:以一定格式进行区分 如 [Length=xxx]xxxxx
        */

        string testStr20 = "product_path";
        Regex rgx12 = new Regex(@"(\w+)(?=_path)");
        RegexCatchTest(testStr20, rgx12);

        string testStr21 = "product_path,jiangwei_path";
        Regex rgx13 = new Regex(@"(\w+)(?=_path)");
        RegexCatchTest2(testStr21, rgx13);

        string testStr22 = @"[Length=17]jiangweiasdasd";
        Regex rgx14 = new Regex(@"(?<=\[Length=)(\d+)(?=\])");
        RegexCatchTest(testStr22, rgx14);


        string testStr23 = @"[Length=17]jiangweiasdasd[Length=21]dasda[lengt= 13";
        Regex rgx15 = new Regex(@"(?<=\[Length=)(\d+)(?=\])");
        RegexCatchTest2(testStr23, rgx15);


        /*
         * 数字截断      
         */      

        string testStr24 = "3.1415926";
        Regex rgx16 = new Regex(@"^\d+\.\d{1,3}");
        RegexCatchTest(testStr24, rgx16);

        /*
         * 修正符
         * 以?开始的修正符
         * (?!) 表示后面所有字符开启不区分大小写模式 (暂未测试成功)
         * (?!:x) 单x不区分大小写
         * */

        string testStr25 = "Ab";
        string testStr26 = "AB";
        Regex rgx17 = new Regex("(?!:a)b");
        Regex rgx20 = new Regex("(?!:ab)");
        RegexMatchTest(testStr25, rgx17);
        RegexMatchTest(testStr26, rgx17);
        RegexMatchTest(testStr25, rgx20);
        RegexMatchTest(testStr26, rgx20);


        /*
           截断测试2
         */

        string testStr27 = "5567";
        string testStr28 = "4313145151756655";
        Regex rgx18 = new Regex("(?<!4)56(?=7)");
        Regex rgx19 = new Regex(@"(?<=4)\d+(?=7)");
        RegexCatchTest(testStr27, rgx18);
        RegexCatchTest(testStr28, rgx19);

        /*
         * 替换  (剔除所有空白字符)
         */      
        string testStr29 = "<Length=25>   dashdkasdhk<Length=24>  dasd  \r\n";
        Regex rgx21 = new Regex(@"\s");
        Debug.Log(rgx21.Replace(testStr29, ""));

        //版本号 替换 
        string testStr30 = "static public string BUILD_VERSION = 1.0; SCrore line";
        Regex rgx22 = new Regex(@"(?<=BUILD_VERSION\s?=\s?).*(?=;)");
        Debug.Log(rgx22.Replace(testStr30, "2.0"));

        //敏感词 替换
        string testStr31 = "我支持香港警察,好了,你们可以打我了!<舆论暴徒,记者>";
        Regex rgx23 = new Regex(@"舆论压力|香港警察");
        Regex rgx24 = new Regex(@"记者|牛逼");
        string temp = rgx23.Replace(testStr31, "****");
        temp = rgx24.Replace(temp, "**");
        Debug.Log(temp);
    }

    //验证函数
    bool RegexMatchTest(string _source, Regex _rgx)
    {
        bool r = false;
        if (String.IsNullOrEmpty(_source) || _rgx == null)
            return r;

        if (_rgx.IsMatch(_source))
        {
            Debug.Log( _source + " Matched " + _rgx.ToString());
            return true; 
        }

        Debug.Log("<color=#ff0000>" + _source + " canot Match " + _rgx.ToString() + "</color>");
        return r; 
    }


    //文件过滤
    string[] RegexScreen(string[] _strs, Regex _rgx)
    {
        List<string> r = new List<string>();

        for (int i = 0; i < _strs.Length; ++i)
        {
            if (_rgx.IsMatch(_strs[i]))
            {
                r.Add(_strs[i]);
                Debug.Log("---->" + _strs[i]);
            } 
        }


        return r.ToArray();
    }

    //捕获测试(单)
    string RegexCatchTest(string _str, Regex _rgx)
    {
        string r = string.Empty;

        if (_rgx.IsMatch(_str))
        {
            r = _rgx.Match(_str).Value;

            Debug.Log("---->" + r);
        }
        return r; 
    }


    //捕获测试(多)
    string[] RegexCatchTest2(string _str, Regex _rgx)
    {
        List<string> rl = new List<string>();

        MatchCollection mc = _rgx.Matches(_str);
        if (mc.Count > 0)
        {
            foreach (var v in mc)
            {
                rl.Add(v.ToString());
                Debug.Log("----->" + v.ToString());
            }
        }

        return rl.ToArray(); 
    }
}
View Code

 

 

posted on 2019-08-15 11:11  未闻花语  阅读(173)  评论(0编辑  收藏  举报