程序员学习 正则表达式


正则表达式:

正则表达式:符合一定规则的操作字符串的表达式

 

特点:将操作字符串的代码封装成特定字符 由特定字符组成正则表达式。这样可以简化代码的书写

 所以学习正则表达式,就是在学习一些特殊符号的使用。

好处:可以简化对字符串的复杂操作。

 弊端:符号定义越多,正则越长,阅读性越差。

 

常用正则表达式规则

字符

x 字符 x

\\ 反斜线字符

\0n 带有八进制值 的字符 n (0 <= n <= 7)

\0nn 带有八进制值 的字符 nn (0 <= n <= 7)

\0mnn 带有八进制值 的字符 mnn0 <= m <= 30 <= n <= 7

\xhh 带有十六进制值 0x 的字符 hh

\uhhhh 带有十六进制值 0x 的字符 hhhh

\t 制表符 ('\u0009')

\n 新行(换行)符 ('\u000A')

\r 回车符 ('\u000D')

\f 换页符 ('\u000C')

\a 报警 (bell) 符 ('\u0007')

\e 转义符 ('\u001B')

\cx 对应于 的控制符

 

字符类

[abc] a或 c(简单类)

[^abc] 任何字符,除了 a或 c(否定)

[a-zA-Z] a 到 或 到 Z,两头的字母包括在内(范围)

[a-d[m-p]] a 到 或 到 p[a-dm-p](并集)

[a-z&&[def]] d或 f(交集)

[a-z&&[^bc]] a 到 z,除了 和 c[ad-z](减去)

[a-z&&[^m-p]] a 到 z,而非 到 p[a-lq-z](减去)

 

预定义字符类

. 任何字符(与行结束符可能匹配也可能不匹配)

\d 数字:[0-9]

\D 非数字: [^0-9]

\s 空白字符:[ \t\n\x0B\f\r]

\S 非空白字符:[^\s]

\w 单词字符:[a-zA-Z_0-9]

\W 非单词字符:[^\w]

边界匹配器

^ 行的开头

$ 行的结尾

\b 单词边界

\B 非单词边界

\A 输入的开头

\G 上一个匹配的结尾

\Z 输入的结尾,仅用于最后的结束符(如果有的话)

\z

输入的结尾

 

正则表达式中具有特定意义的字符注意一定的转义  如果没有在字符串的转义里定义就得经过2次转义。。

 

正则表达式中.代表所有字符的意思 所有你不想让它代表所有字符的意思的话可以写到一对中括号内如[.] 也可以用转义字符转义 如果要转义的话要用2个转义字符如\\.

 

\.这样写编译不会通过因为正则表达式是写在字符串内的 字符串检测到子窜里有转义符所有就会先被字符串转义而字符串转义里面没有\. 所有编译器不识别报错。。

 

\\.先被字符串转义成\. 在经过正则表达式转义 所有在字符串转义里面没有的要经过2次转义 而字符串转义里面已定义的只要被字符串转义就可以了 正则表达式里面可以转义也可以不转义 如\\n\n 都是可以的  

 

组是正则表达式用来封装部分正则的封装体 就跟函数体里封装的是代码一样 组可以内嵌 就跟类里面还可以封装类部类一样  每个组都有指针 通过指针操作组 指针0表示整个正则表达式  所以组的指针从1开始  在正则表达式内部调用组用\指针 由于要经过字窜转义所以写成\\指针  在参数列表内调用定一个正则表达式的组应该用$指针

 

捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C))) 中,存在四个这样的组:

 

1     ((A)(B(C)))

2     \A

3     (B(C))

4     (C)

组零始终代表整个表达式。

 

正则表达式操作步骤: 当然头前3个功能也可以不完全按照这个来直接操作StringPattern类也可以 如果是地4个功能或其他功能就要按照这个来了

 

1.按指定的模式将正则表达式编译封装成正则表达式对象

 

通过Pattern类的compile方法

 

static Pattern compile(String regex)

          将给定的正则表达式编译到模式中。

static Pattern compile(String regex, int flags)

          将给定的正则表达式编译到具有给定标志的模式中。

 

 

2. 让正则表达式对象和要操作的字符串序列按模式执行匹配操作创建获取匹配引擎   也可以理解为让正则对象和要操作的字符串相关联,关联后,获取正则匹配引擎。

 

通过Pattern类的matcher方法

 

Matcher matcher(CharSequence input)

          创建匹配给定输入与此模式的匹配器。

 

 

3.通过匹配器引擎对符合规则的子串进行操作,比如取出。

 

 

 

具体操作功能:

 

1,匹配:用规则匹配整个字符串,只要有一处不符合规则,就匹配结束,返回false

 

String

 

 boolean matches(String regex)

          告知此字符串是否匹配给定的正则表达式。

Pattern

 

static boolean matches(String regex,CharSequence input) 

          编译给定正则表达式并尝试将给定输入与其匹配。

Matcher类 

 

 boolean matches() 

          尝试将整个区域与模式匹配。

String类和Pattern类的matches方法调用的是Matcher类的matches方法 被String Pattern的方法封装后,用起来较为简单。但是功能不够多。就如Math类的random方法调用的Random类的nextDoube  它只能直接生产01的双精度小数  Random的方法丰富的多可以直接生成整数boolean等其他类型的数

事例:验证qq号是否合法

mport java.io.FileInputStream;  

import java.io.FileNotFoundException;  

import java.io.IOException;  

import java.io.InputStream;  

import java.net.MalformedURLException;  

import java.net.URL;  

import java.util.Arrays;  

import java.util.Comparator;  

import java.util.regex.Matcher;  

import java.util.regex.Pattern;  

public class RegexDemo {  

      

    public static void main(String[] args) {  

        String regex;  

        String qq="233322232";  

        regex="[1-9]\\d{4,13}";  

        checkQQ(qq,regex);  

          

        String tel="13986868886";  

        regex="1[358]\\d{9}";  

        checkTel(tel,regex);  

          

        String mail="adadsfadsf@163.COM";  

        regex="\\w{6,14}@[a-zA-Z0-9]+(\\.[a-zA-Z]+)+";//相对精准  

        regex="\\w{6,14}@\\w+(\\.\\w+)+";//不太精准  

        checkMail(mail,regex);  

          

 

2,切割:用规则匹配整个字符串,获取不符合规则的子窜

 

String

 

String[] split(String regex)

          根据给定正则表达式的匹配拆分此字符串。

 String[] split(String regex, int limit)

          根据匹配给定的正则表达式来拆分此字符串。  

Pattern

 

 String[] split(CharSequence input)

          围绕此模式的匹配拆分给定输入序列。

 String[] split(CharSequence input, int limit)

          围绕此模式的匹配拆分给定输入序列。

举例:

 //按照.切割   由于.在正则表达式中代表所有字符所有要转义 而又没在字符串转义里注册所以要用到2个转义符号  

        String name="zhangsan.lisi.wangwu";  

        regex="\\.";  //或者写成regex=[.];  

        split(name,regex);  

          

        //按照叠词切割  

        name="erkktyqqquizzzzzo";  

        regex="(.)\\1+";  

        split(name,regex);  

          

        //按照任意个空格进行切割  

        name="zhangsan wangwu    zhaoliu    lisi              wangqi   ";  

        regex=" +";  

        split(name,regex);  

          

        //5位以上的数字替换成$号  

        String str ="wer1389980000ty1234564uiod234345675f";  

        regex="\\d{5,}";  

        String newStr="\\$"; //$要被转义因为在正则表达式中它用来调用组。。  

        replaceAll(str,regex,newStr);  

          

        //将重复出现的叠词替换成单个字母  

        str= "erkktyqqquizzzzzo";  

        regex="(.)\\1+";  

        newStr="$1";   //$通过组指针调用组  

        replaceAll(str,regex,newStr);  

          

        //去掉空格和.在把叠字换成单个的字  

        textFormat();  

          

        //获取符合规则的字串和指针  

        getDemo();  

          

        //ip地址排序  

        ipOldSort();  

        ipSort();  

        //从文件和网上获取Email地址  

        getEmailForFile();  

        getEmailForURL();  

    }  

 

3,替换:用规则匹配整个字符串 按条件用新的子窜替换符合规则的子窜    replacement为新的子窜

 

String

replaceAll(String regex,String replacement)   

 

          使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。

 

 String replaceFirst(String regex,String replacement) 

          使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。

String

 

replaceAll(String replacement)

          替换模式与给定替换字符串相匹配的输入序列的每个子序列。

 

 String

 

replaceFirst(String replacement)

          替换模式与给定替换字符串匹配的输入序列的第一个子序列。

 

 *需求: 

     *将下列字符串转成:我要学编程

     */  

    static void textFormat(){  

        String str = "我我...我     我我...我      要要..要             要...要要..." +  

                "学学....学学..........编                  编...编程...程程......";  

        //可以先把.和空格去掉在把重复的字编程单个的字  

        String regex="[. ]+";  

        replaceAll(str,regex, "");  

        str=str.replaceAll(regex, "");  

        regex="(.)\\1+";  

        replaceAll(str,regex,"$1");  

    }  

      

 

 

4、获取:将字符串中符合规则的子串取出 

步骤:
       1、将正则表达式封装成对象。Pattern p = Pattern.complite(regex) ;
       2、让正则对象和要操作的字符串相关联,获取正则匹配引擎。Matcher m = p.matcher(string) ; 
       3、通过引擎对符合规则的子串进行操作。

例如:

 public static void getDemo(){  

        String str = "ming tian jiu yao fang jia le ,da jia";  

        System.out.println(str);  

        String regex = "\\b[a-z]{4}\\b";  

  

        //将规则封装成对象。  

        Pattern p = Pattern.compile(regex);  

  

        //将正则对象和字符串按模式执行匹配操作获取匹配引擎  

        Matcher m  = p.matcher(str);  

          

        //find将规则作用到字符串上,并进行符合规则的子串查找。  

          

        //如果这里执行了m.matches(regex);那么指针将从t开始   

        while(m.find()){  

            //group用于获取匹配后结果。  

            System.out.println(m.group());  

            //start end 用来获取匹配前后指针  

            System.out.println(m.start()+"...."+m.end());  

        }  

    }  

 

以上四种功能到底用四种功能中的哪一个呢?或者哪几个呢?

 思路方式:

 1,如果只想知道该字符是否对是错,使用匹配。

 2,想要将已有的字符串变成另一个字符串,替换。

 3,想要按照自定的方式将字符串变成多个字符串。切割。获取规则以外的子串。

 4,想要拿到符合需求的字符串子串,获取。获取符合规则的子串。

i

       

 

    /*

      练习:

    /** 

     * ip地址进行地址段顺序的排序。 

     * 这是没用正则表达式的情况 

     */  

    static void ipOldSort(){  

      

        String ip="192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30";  

        String[] ips=ip.split(" ");  

        Arrays.sort(ips,new Comparator<String>(){  

            @Override   

            public int compare(String s1,String s2){  

                //.在正则表达式里表示所有字符不想表示所有字符的话就一定记得转义  

                //比较2个数字字符串的大小不要用compareTo比较 要转换成Integer在比较  

                String[] tmpS1s=s1.split("[.]");  

                String[] tmpS2s=s2.split("\\.");  

                int ret=0;  

                for(int i=0;i<tmpS1s.length;i++){  

                    ret=Integer.parseInt(tmpS1s[i])-Integer.parseInt(tmpS2s[i]);  

                    if(ret!=0){  

                        break;  

                    }  

                }  

                return ret;  

            }  

        });  

        out.println("old ip sort:"+Arrays.toString(ips));  

    }  

      

    static void ipSort(){  

        String ip="192.168.1.2 11.1.3.4 0.32.32.34 10.2.4.3 2.3.4.2";  

        //首先把每个IP地址的每个段头前都补20  在让每个段都成3位  

        String regex="(\\d+)";  

        ip=ip.replaceAll(regex, "00$1");  

        regex="0*(\\d{3})";  

        ip=ip.replaceAll(regex, "$1");  

        //在通过空格切割这个字串  

        String[] ips=ip.split(" +");  

        //通过Arrays.sort进行排序  

        Arrays.sort(ips);  

        //输出  

        for(int index=0;index<ips.length;index++){  

            ips[index]=ips[index].replaceAll("0*(\\d+)","$1");  

        }  

        System.out.println("new ip sort:"+Arrays.toString(ips));  

    }  

      

    /** 

     * 更具文件爬Email 

     */  

    static void getEmailForFile(){  

        try {  

            FileInputStream fis=new FileInputStream("g:/mail.txt");  

            getEmail(fis);  

        } catch (FileNotFoundException e) {  

            System.out.println("g:/mail.txt文件不存在或者是目录或权限不够或隐藏等等");  

        }  

          

    }  

      

    static void getEmailForURL(){  

        try {  

            InputStream in=new URL("http://192.168.1.245:8080/").openStream();  

        } catch (MalformedURLException e) {  

            System.out.println("建立连接失败请检查域名端口是否错误");  

        } catch (IOException e) {  

            System.out.println("IO错误");  

        }  

          

    }  

    /** 

     * 网页爬虫(蜘蛛

     */  

    static void getEmail(InputStream in){  

            StringBuilder sb=new StringBuilder();  

            byte[] buf=new byte[1024];  

            try {  

                for(int len;(len=in.read(buf))!=-1;){  

                    sb.append(new String(buf,0,len));  

                }  

            } catch (IOException e) {  

                System.out.println("IO流读取操作错误");  

            }finally{  

                if(in!=null){  

                    try {  

                        in.close();  

                    } catch (IOException e) {  

                        System.out.println("IO输入流关闭错误");  

                    }  

                }  

            }  

            String regex="(\\w)+@\\w+(\\.\\w{2,})+";  

            Pattern pattern=Pattern.compile(regex);  

            Matcher matcher=pattern.matcher(sb.toString());  

            while(matcher.find()){  

                System.out.println(matcher.group());  

            }  

        }  

  

}  

 

内容概要:本文详细探讨了基于MATLAB/SIMULINK的多载波无线通信系统仿真及性能分析,重点研究了以OFDM为代表的多载波技术。文章首先介绍了OFDM的基本原理和系统组成,随后通过仿真平台分析了不同调制方式的抗干扰性能、信道估计算法对系统性能的影响以及同步技术的实现与分析。文中提供了详细的MATLAB代码实现,涵盖OFDM系统的基本仿真、信道估计算法比较、同步算法实现和不同调制方式的性能比较。此外,还讨论了信道特征、OFDM关键技术、信道估计、同步技术和系统级仿真架构,并提出了未来的改进方向,如深度学习增强、混合波形设计和硬件加速方案。; 适合人群:具备无线通信基础知识,尤其是对OFDM技术有一定了解的研究人员和技术人员;从事无线通信系统设计与开发的工程师;高校通信工程专业的高年级本科生和研究生。; 使用场景及目标:①理解OFDM系统的工作原理及其在多径信道环境下的性能表现;②掌握MATLAB/SIMULINK在无线通信系统仿真中的应用;③评估不同调制方式、信道估计算法和同步算法的优劣;④为实际OFDM系统的设计和优化提供理论依据和技术支持。; 其他说明:本文不仅提供了详细的理论分析,还附带了大量的MATLAB代码示例,便于读者动手实践。建议读者在学习过程中结合代码进行调试和实验,以加深对OFDM技术的理解。此外,文中还涉及了一些最新的研究方向和技术趋势,如AI增强和毫米波通信,为读者提供了更广阔的视野。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值