正则表达式 Regular Expression

2024-05-11 04:38

本文主要是介绍正则表达式 Regular Expression,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

重新整理记录一下正则规则

一、定义

Regular Expression - 正规的/有规律的表达式,是计算机科学的一个概念。使用一个字符串来描述、匹配一系列符合某个句法规则的字符串

最初这个概念是由Unix中的工具软件如sed和grep普及开的,通常简写为regex ['ridʒɛks]

几乎所有操作系统以及编程语言中都有正则表达式的应用

二、引擎

正则引擎主要分为两大类:

  • DFA
  • NFA
  • POSIX NFA

一. DFA引擎
速度:最快
特点:以文本为主导
主要使用者:awk、egrep、flex、lex、MySQL、Procmail

二. NFA引擎
速度:次之
特点:以表达式为主导,更容易操纵,一般程序员更偏爱NFA
只要使用者:GNU Emacs、Java、ergp、less、.NET、PCRE

三. POSIX NFA
意义:为了防止继续出现不同引擎的变体而产生的统一引擎
速度:最慢
使用者:mawk、GNU Emacs(使用时显式指定)

三、表达式的构造

表达式的基本思路:对字符串中的字符一个一个的进行匹配

构造匹配
Characters - 字符
x字符x就带表某个字符x
\\backslash 反斜杠
\0noctal 八进制数n
\xhhhexadecimal 十六进制数hh
\uhhhhhexadecimal 十六进制数hhhh
\ttab 制表符(‘\u0009’)
\nnewline 新行(‘\u000A’)
\rcarriage return 回车(‘\u000D’)
Character classes - 字符类型
[abc]a,b, or c
[^abc]exclusive OR 任意character except a,c, or c
[a-zA-Z]a through z or A through Z
[a-d[m-p]]并集,相当于[a-dm-p]
[a-z&&[bcd]]交集,相当于[bcd]
[a-z&&[^bc]]交集,相当于[ad-z]
Predefined character classes - 预定义的字符类型
.任意character
\dA digit:[0-9]
\DA non-digit:[^0-9]
\swhitespace:[ \t\n\x0B\f\r],注意中括号的第一个字符是空格(ASCII32)不是\t
\Snon-whitespace:[^\s]
\wA word:[a-zA-Z_0-9]
\WA non-word:[^\w]
Boundary matchers - 边界匹配器
^The beginning of a line
$The end of a line
\bA word boundary
\BA non-word boundary
Greedy quantifiers - 贪婪量词
X?X出现一次或not at all
X*X出现0次或多次
X+X出现一次或多次
X{n}X固定出现n次
X{n,}X至少出现n次
X{n,m}X出现n到m次
Reluctant quantifiers - 勉强量词由Greedy加”?”构成
X??X出现一次或not at all
X*?X出现0次或多次
X+?X出现一次或多次
X{n}?X固定出现n次
X{n,}?X至少出现n次
X{n,m}?X出现n到m次
Possessive quantifiers - 独占量词由Greedy加”+”构成
X?+X出现一次或not at all
X*+X出现0次或多次
X++X出现一次或多次
X{n}+X固定出现n次
X{n,}+X至少出现n次
X{n,m}+X出现n到m次
Logical operators - 逻辑操作符
XYX后面跟Y
XY
(X)X,作为一个捕获组capturing group
Back references - 引用捕获组
\n代表捕获组中的第n个,第0个默认代表整个表达式
Special constructs - 特殊构造包括非捕获组
(?:X)X作为非捕获组
(?=X)X通过零宽度正向预测先行断言,匹配X前面的位置
(?!X)X通过零宽度负预测先行断言,匹配后面跟的不是exp的位置
(?<=X)X通过零宽度正回顾后发断言,匹配X后面的位置
(?X通过零宽度负回顾后发断言,匹配前面不是X的位置
(?>X)X作为独立组,非捕获

TIPS:
零宽度断言用于匹配那些:在X之前或之后的需求

四、一些点

1. Groups and capturing 组和捕获

捕获组的编号通过从左至右数左括号来编号,如表达式((A)(B(C)))中,

0:始终代表整个表达式
1:((A)(B(C)))
2:(A)
3:(B(C))
4:(C)

捕获的子序列可以通过上面说的Back references在表达式中使用

2. Backslash 反斜线

\Backslash反斜线用于:

  1. 引用转义构造
  2. 引用其它应该被解释为非转义构造的字符(转义字符想要正常使用)
  3. 另外,在Java中字符串中的反斜线被视为Unicode转义(写法\uxxxx)或其它字符转义,因此需要使用两个反斜线来代表原意

五、Java中

使用到的各种情况,功能直接或间接都是由java.util.regex包中的两个类Pattern和Matcher的方法来完成的

  1. Pattern类
    正则表达式的编译表示形式

    指定为字符串的正则表达式必须首先被编译为此类的实例:

    Pattern p = Pattern.compile(regex);

    Pattern只创建正则对象,而具体功能的实现则由Matcher类提供,典型的调用顺序是:

    Pattern p = Pattern.compile("a*b");
    Matcher m = p.matcher("aaaaaab");
    boolean b = m.matches();
  2. Matcher类
    通过解释某个固定的Pattern从而对固定character sequence执行匹配操作的引擎

    Matcher对象一经建立,其Pattern和String都已经确定了

    匹配器可以执行3种不同的匹配操作:

    1. matches
      将整个输入序列与该模式进行匹配
    2. lookingAt
      将输入序列从头开始与该模式匹配
    3. find
      扫描输入序列以查找与该模式匹配的下一个子序列

    当由以上3个中任意一个匹配方法匹配成功后,就可做很多事情了,如:
    m.group();//获取刚刚匹配的输入子序列
    m.start();//获取刚刚匹配的输入子序列的开始索引
    m.end();//同上,结束索引

1. 匹配

/*** 1. 匹配*  方法:使用String的matches()*  规则:第一位必须是1,第二位可以是3/5/8,后面是9位数字*/
String str1 = "13812312319";
String regex1 = "1[358]\\d{9}";
System.out.println(str1.matches(regex1));//true

2. 分割

/*** 2. 分割*  方法:使用String的split()*  目标:*  2.1 任意个空格的分割*  2.2 以.分割:需要注意取消.在正则中代表任意字符的含义*  2.3 重复的字符来分割,需要使用分组,因为要求第2个字符跟第1个相同*/
String str21 = "asdf 909  sdfd sadf           sdf";
String regex21 = "\u0020+";//空格就是\u0020(十进制32),也可以直接敲个 (前面是个空格),或者使用\\s
String [] strs21 = str21.split(regex21);String str22 = "asdf.909.sdfd.sadf.sdf";
String regex22 = "\\.";//首先\.代表想正常使用点(而不是正则字符),又因为在Java的String中,所以再加\
String [] strs22 = str22.split(regex22);String str23 = "asdfssss909aaaasdfdbbbbbsadfttttsdf";
String regex23 = "([a-z])\\1+";//首先,第一个字符是任意小写英文;接着,第二个字符和第一个一样;最后,第二个字符出现至少一次
String [] strs23 = str23.split(regex23);

3. 替换

/*** 3. 替换*  方法:使用String的replaceAll()*  目标:*  3.1 简单替换*  3.2 使用被替换的内容替换,将重复的变为1个:需使用组,可以在方法第二个参数中使用美元符号$选取组*  3.3 手机号码中4位用*号代替*/
String str31 = "asdf 909  sdfd sadf           sdf";
String regex31 = "\u0020+";
str31 = str31.replaceAll(regex31, "1");//asdf19091sdfd1sadf1sdfString str32 = "asdf 909  sdfd sadf           sdf";
String regex32 = "(\u0020)+";
str32 = str32.replaceAll(regex32, "$1");//asdf 909 sdfd sadf sdfString str33 = "13812312319";
String regex33 = "(.{3}).{4}(.{4})";//将需要保留的内容编组保留,以便之后还原,然后整体替换
str33 = str33.replaceAll(regex33, "$1****$2");

4. 获取

/*** 4. 获取*  方法:创建一个匹配给定输入(String)和给定模式(Pattern)的匹配器(Matcher)*  目标:*  4.1 获取3个字母组成的单词*/
String str41 = "asdf, sdd*adf%$$sdsf";
String regex41 = "[a-z]{3}";
Pattern p = Pattern.compile(regex41);//创建正则模式对象
Matcher m = p.matcher(str41);//创建根据固定字符串和模式的匹配器
while(m.find()){//查找一个匹配的子序列System.out.println(m.group());//返回之前匹配的输入子序列
}

完整的学习正则表达式和Java中的正则,我推荐两个地址:

正则表达式30分钟入门教程
JavaSE8的API中的java.util.regex.Pattern类

正则表达式所有东西还是不少的,较为复杂,而且平常使用的只是一小部分,没有必要全学完
可以学会常用的,不常用的用到时去上面两个地方查询






20161126 突然想到应该记录下,自己用到的正则

常用正则表达式记录

  1. JavaBean中给private字段加空注释

    /*** */

    find:private
    Replace with:/*\r\n\u0009\u0020\u0020\r\n\u0009\u0020*/\r\n\u0009private

这篇关于正则表达式 Regular Expression的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/978525

相关文章

JavaScript正则表达式六大利器:`test`、`exec`、`match`、`matchAll`、`search`与`replace`详解及对比

在JavaScript中,正则表达式(Regular Expression)是一种用于文本搜索、替换、匹配和验证的强大工具。本文将深入解析与正则表达式相关的几个主要执行方法:test、exec、match、matchAll、search和replace,并对它们进行对比,帮助开发者更好地理解这些方法的使用场景和差异。 正则表达式基础 在深入解析方法之前,先简要回顾一下正则表达式的基础知识。正则

匹配电子邮件地址的正则表达式

这个正则表达式 QRegularExpression regex(R"((\w+)(\.|_)?(\w+)@(\w+)(\.(\w+))+))"); 用于匹配电子邮件地址的格式。下面是对这个正则表达式的逐步解析和解释: 1. QRegularExpression 构造函数 QRegularExpression regex(R"((\w+)(\.|_)?(\w*)@(\w+)(\.(\w+))+

notepad++ 正则表达式多条件查找替换

基础语法参考: https://www.cnblogs.com/winstonet/p/10635043.html https://www.linuxidc.com/Linux/2019-05/158701.htm   通常情况下我们查找的内容和要被替换掉的内容是一样的,我们只需要使用正则表达式精确框定查找内容,替换直接输入要替换的内容即可。 但有时会比较复杂,查找的内容,只需要替换其中

js正则表达式test方法的问题

今天在网上碰到一个帖子,写了一个关于Regex的奇怪现象,(文章来源http://www.php100.com/html/webkaifa/javascript/2007/0109/1866.html) 代码如下 <script type="text/javascript"><!--var re = /^\d+(?:\.\d)?$/ig; alert(re.test('112.3'

Java利用正则表达式获取指定两个字符串之间的内容

package com.starit.analyse.util;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.List;import java.util.regex.Matcher;import java.util.regex.Pattern;public class DealSt

leetcode#10. Regular Expression Matching

题目 Implement regular expression matching with support for ‘.’ and ‘*’. '.' Matches any single character.'*' Matches zero or more of the preceding element.The matching should cover the entire input

AS3中正则表达式中如何表达“或”

var reg:RegExp=/\r|\n|\t/g;                 var msg:String="123\rabc\n\tabc\ta\123";                 msg=msg.replace(reg,"");                 trace(msg);

as3 正则表达式(比较齐全)

正则表达式是AS3比较重要的一个部分,具体内容如下:   //正则表达式有四个部分。1元子符。2元序列。3标志。4数量表达符。 //下面是元字符部分 //现在我们来看看元字符: ^ $ \ . * + ? ( ) [ ] { } | //^匹配字符串的开头 varpattern:RegExp=/^小虫/; var str:String="小虫是好人"; trace(str, " is

as3 常用正则表达式(来自天地会论坛之七夜)

正则表达式是一种通用的标准,大部分计算机语言都支持正则表达式,包括as3,这里转摘出了一些常用的正则表达式语句,大家用到的时候就不用自己写了。 红色字体为常用正则: 下面这个类是我自己写的一个示例,想必大家做客户端,用户登录信息肯定会用的正则表达式。 package com.qiye.regexp { /**   * 常用正则表达式。   * @author Qiy

认识正则表达式

为什么要学习正则表达式 因为爬虫需要!!! 一般来说爬虫需要四个主要步骤: 明确目标 (要知道你准备在哪个范围或者网站去搜索)爬 (将所有的网站的内容全部爬下来)取 (去掉对我们没用处的数据)处理数据(按照我们想要的方式存储和使用) 一般情况我们拉取的网页数据庞大并且很混乱,其中很大一部分东西是我们不关心的,因此我们需要将其按要求过滤和匹配出来。 那么对于文本的过滤和指定规则的匹配,最