正则表达式模式匹配字符串基础知识

 介绍

在实际项目中有个功能的实现需要解析一些特定模式的字符串。而在已有的代码库中,在已实现的部分功能中,都是使用检测特定的字符,使用这种方法的缺点是:

  • 逻辑上很容易出错
  • 很容易漏掉对一些边界条件的检查
  • 代码复杂难以理解、维护
  • 性能差

看到代码库中有一个cpp,整个cpp两千多行代码,有个方法里,光解析字符串的就有400余行!一个个字符对比过去,真是不堪入目。而且上面很多注释都已经过期,很多代码的书写风格也各不相同,基本可以判断是过了很多人手的。

在这种情况下,基本没办法还沿着这条老路走下去,自然而然就想到了使用正则表达式。而我自己在正则表达式方面没有实际应用的经验,尤其是对于书写匹配规则也是一知半解。第一时间就想到从网上找点资料,先大致了解下。但是度娘的结果依旧还是让人很失望。(当然,如果是想要查找一些比较专业的知识,度娘的结果每次都会让人心碎,无不都是千篇一律的拷贝。但是通常度娘生活方面的还是可以)后来就放弃度娘的查询结果,FQ到了外面去找,也找到了一些比较基础的视频(需FQ)。

这篇文章可以说是一个总结,把在书写正则表达式的匹配字符串方面的基础知识介绍一下。主要分为以下两个个部分:

  1. 匹配字符串的基本规则
  2. 正则匹配、查找与替代

本文介绍的正则表达式规则是ECMAScript。使用的编程语言是C++。其他方面的不做介绍。

匹配字符串的基本规则

1. 匹配固定的字符串

regex e("abc");

2. 匹配固定字符串,不区分大小写

regex e("abc", regex_constants::icase);

3. 匹配固定字符串之外多一个字符,不区分大小写

regex e("abc.", regex_constants::icase);  // .  Any character except newline. 1个字符

4. 匹配0个或1个字符

regex e("abc?");    // ?  Zero or 1 preceding character. 匹配?前一个字符

5. 匹配0个或多个字符

regex e("abc*");    // *  Zero or more preceding character. 匹配*前一个字符

6. 匹配1个或多个字符

regex e("abc+");    // +  One or more preceding character. 匹配+前一个字符

7. 匹配特定字符串中的字符

regex e("ab[cd]*");    // [...] Any character inside square brackets. 匹配[]内的任意字符

8. 匹配非特定字符串的字符

regex e("ab[^cd]*");    // [...] Any character not inside square brackets. 匹配非[]内的任意字符

9. 匹配特定字符串,且指定数量

regex e("ab[cd]{3}");    // {n}  匹配{}之前任意字符,且字符个数为3个

10. 匹配特定字符串,指定数量范围

regex e("ab[cd]{3,}");  // {n} 匹配{}之前任意字符,且字符个数为3个或3个以上
regex e("ab[cd]{3,5}");  // {n} 匹配{}之前任意字符,且字符个数为3个以上,5个以下闭区间

11. 匹配规则中的某一个规则

regex e("abc|de[fg]");    // |  匹配|两边的任意一个规则

12. 匹配分组

regex e("(abc)de+");    // ()       ()表示一个子分组

13. 匹配子分组

regex e("(abc)de+\\1");  // ()    ()表示一个子分组,而\1表示在此位置匹配第一个分组的内容
regex e("(abc)c(de+)\\2\\1");  // \2 表示的是在此匹配第二个分组的内容

14. 匹配某个字符串开头

regex e("^abc.");
// ^ begin of the string 查找以abc开头的子字符串

15. 匹配某个字符串结尾

regex e("abc.$");
// $ end of the string 查找以abc结尾的子字符串

以上是最基本的匹配模式的书写。通常如果要匹配特定的字符,需要使用\进行转义,比如在匹配字符串中需要匹配".",那么在匹配字符串中应该在特定字符前加上\。出了以上的基本规则,如果还不满足特定的需要,那么可以参考此链接。使用了解基本的匹配模式后,需要使用正则表达式进行匹配、查找或者替代。

正则匹配、查找与替代

书写好模式字符串后,需要将待匹配的字符串和模式字符串进行一定规则的匹配。包括三种方式:匹配(regex_match)、查找(regex_search)、替换(regex_replace)。

匹配很简单,直接将待匹配字符串和模式字符串传入到regex_match中,返回一个bool量来指明待匹配的字符串是否满足模式字符串的规则。匹配整个str字符串。

bool match = regex_match(str, e);
// 匹配整个字符串str

查找是在整个字符串中找到和满足模式字符串的子字符串。也就是只要str中存在满足模式字符串就会返回true。

bool match = regex_search(str, e);
// 查找字符串str中匹配e规则的子字符串

但是很多情况下,光是返回一个是否匹配的bool量是不够的,我们需要拿到匹配的子字符串。那么就需要在模式字符串中将匹配字符串分组,参考【匹配字符串的基本规则】第12点。再将smatch传入到regex_search中,就可以获得满足每个子分组的字符串。

smatch m;
bool found = regex_search(str, m, e);
for (int n = 0; n < m.size(); ++n)
  {
    cout << "m[" << n << "].str()=" << m[n].str() << endl;
  }

替换也是基于模式字符串在分组情况下完成的。

cout << regex_replace(str, e, "$1 is on $2");

此时,会在满足分组1和分组2的字符串中间加上“ is on”。

以上三个函数有很多版本的重载,可以满足不同情况下的需求。

实战

要求:找出满足sectionA("sectionB")或者sectionA ("sectionB")的模式字符串。且分离出sectionA、sectionB。sectionA和sectionB不会出现数字,字符可大小写,至少有一个字符。

分析:根据要求,大致可分为两个部分,也就是sectionA和sectionaB。这是就需要用到分组。

第一步:写出满足section情况的模式字符串

[a-zA-Z]+

第二步:在sectionA和sectionB中可能会出现空格。暂且假设至多有1个空格

\\s?

将以上两个情况组合起来,也就是能满足我们需求的模式字符串。但是如何组织才能让其分为两组呢?

[a-zA-Z]+\\s[a-zA-Z]+

上面这种写法肯定不对的,根据分组规则,需要将分组以()进行区分

regex e("([a-zA-Z]+)\\s?\\(\"([a-zA-Z]+)\"\\)");

此时,在\\s?后面的\\(\"是为了满足sectionB外层的引号和括号进行的转义。

以上完成后,可先用regex_match进行匹配,如果匹配,那么继续使用regex_search对字符串进行查找

if (regex_match(str, e))
{
 smatch m;
 auto found = regex_search(str, m, e);
 for (int n = 0; n < m.size(); ++n)
 {
 cout << "m[" << n << "].str()=" << m[n].str() << endl;
 }
}
else
{
 cout << "Not matched" << endl;
}

对象m数组的第一个字符串是满足需求的整个子串,接下来才是满足分组1、分组2的子串。

总结

以上所述是小编给大家介绍的正则表达式模式匹配字符串基础知识,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • 正则表达式实现字符的模糊匹配功能示例

    本文实例讲述了正则表达式实现字符的模糊匹配功能.分享给大家供大家参考,具体如下: package com.cn.util; import java.util.regex.Pattern; /** * 正则表达式 工具类 * * @author lifangyu */ public class RegexUtil { /* * IP地址的匹配标达式 ( // \\d{1,3}) // :\d // 0~9数字,{1,3} // 至少一位,最多三位) */ private static String

  • 比较常用的几个正则表达式匹配数字(收藏)

    正则表达式用于字符串处理.表单验证等场合,实用高效.现将一些常用的表达式收集于此,以备不时之需. 匹配中文字符的正则表达式: [\u4e00-\u9fa5] 评注:匹配中文还真是个头疼的事,有了这个表达式就好办了 匹配双字节字符(包括汉字在内):[^\x00-\xff] 评注:可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1) 匹配空白行的正则表达式:\n\s*\r 评注:可以用来删除空白行 匹配HTML标记的正则表达式:<(\S*?)[^>]*>.*?</\1

  • 正则表达式中最短匹配模式的用法浅析

    前言 最近有一次想用正则表达式从网页里面抓取一些东西出来,内容不复杂却出现不少问题.下面话不多说,来一起看看详细的介绍: 当我们用正则表达式去匹配一个标签的首尾的时候,比如匹配 <h1>hello world</h1> 中的 h1 的开始和闭合标签 可能很多人会这样写 /<.*h1>/g 但是这样真的可以吗? 因为 * 匹配符是匹配前面一个字符的零到多个,而且它是贪婪匹配的 所以你得到的就会是下面的结果了. 显然这并不是我们想要的,那么怎么把贪婪匹配换成最小匹配呢, /

  • 浅析一个匹配数字和字母密码的正则表达式

    一个用户注册功能的密码有如下要求:由数字和字母组成,并且要同时含有数字和字母,且长度要在8-16位之间. 如何分析需求?拆分!这就是软件设计的一般思路了.于是乎,拆分需求如下: 1,不能全部是数字 2,不能全部是字母 3,必须是数字或字母 只要能同时满足上面3个要求就可以了,写出来如下: ^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$ 分开来注释一下: ^ 匹配一行的开头位置 (?![0-9]+$) 预测该位置后面不全是数字 (?![a-zA-Z]+$)

  • Java基于正则表达式实现查找匹配的文本功能【经典实例】

    本文实例讲述了Java基于正则表达式实现查找匹配的文本功能.分享给大家供大家参考,具体如下: REMatch.java: package reMatch; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Created by Frank */ public class REMatch { public static void main(String[] args) { String patt = "Q[^

  • C#正则表达式匹配与替换字符串功能示例

    本文实例讲述了C#正则表达式匹配与替换字符串功能.分享给大家供大家参考,具体如下: 事例一:\w+=>[A-Za-z1-9_],\s+=>任何空白字符,()=>捕获 string text = @"public string testMatchObj string s string match "; string pat = @"(\w+)\s+(string)"; // Compile the regular expression. Regex

  • Java正则表达式实现在文本中匹配查找换行符的方法【经典实例】

    本文实例讲述了Java正则表达式实现在文本中匹配查找换行符的方法.分享给大家供大家参考,具体如下: 默认情况下,正则表达式 ^ 和 $ 忽略行结束符,仅分别与整个输入序列的开头和结尾匹配.如果激活 MULTILINE 模式,则 ^ 在输入的开头和行结束符之后(输入的结尾)才发生匹配.处于 MULTILINE 模式中时,$ 仅在行结束符之前或输入序列的结尾处匹配. NLMatch.java: package nlMatch; import java.util.regex.Pattern; /**

  • 正则表达式匹配(URL、电话、手机、邮箱)的实例代码

    正则表达式,又称规则表达式.(英语:Regular Expression,在代码中常简写为regex.regexp或RE),计算机科学的一个概念.正则表通常被用来检索.替换那些符合某个模式(规则)的文本.下面通过实例代码给大家介绍正则表达式匹配(URL.电话.手机.邮箱)的实例代码,一起看看吧! 废话不多说了,直接给大家贴代码了,具体代码如下所示: <!DOCTYPE html> <html lang="en"> <head> <meta ch

  • JS匹配日期和时间的正则表达式示例

    本文实例讲述了JS匹配日期和时间的正则表达式.分享给大家供大家参考,具体如下: //日期的正则表达式 var reg = /^[1-9]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/; var regExp = new RegExp(reg); if(!regExp.test(value)){ alert("日期格式不正确,正确格式为:2014-01-01"); return; } //时间的正则表达式 var reg = /^(2

  • 正则表达式模式匹配字符串基础知识

     介绍 在实际项目中有个功能的实现需要解析一些特定模式的字符串.而在已有的代码库中,在已实现的部分功能中,都是使用检测特定的字符,使用这种方法的缺点是: 逻辑上很容易出错 很容易漏掉对一些边界条件的检查 代码复杂难以理解.维护 性能差 看到代码库中有一个cpp,整个cpp两千多行代码,有个方法里,光解析字符串的就有400余行!一个个字符对比过去,真是不堪入目.而且上面很多注释都已经过期,很多代码的书写风格也各不相同,基本可以判断是过了很多人手的. 在这种情况下,基本没办法还沿着这条老路走下去,自

  • Python 专题三 字符串的基础知识

    在Python中最重要的数据类型包括字符串.列表.元组和字典等.该篇主要讲述Python的字符串基础知识. 一.字符串基础 字符串指一有序的字符序列集合,用单引号.双引号.三重(单双均可)引号引起来.如: s1='www.csdn.NET'   s2="www.csdn.Net"   s3='''aaabbb''' 其中字符串又包括: 1.转义字符串 像C语言中定义了一些字母前加"\"来表示常见的那些不能显示的ASCII字符,python也有转义字符.如下:   \

  • MySQL 字符串模式匹配 扩展正则表达式模式匹配

    标准的SQL模式匹配 SQL的模式匹配允许你使用"_"匹配任何单个字符,而"%"匹配任意数目字符(包括零个字符).在 MySQL中,SQL的模式缺省是忽略大小写的.下面显示一些例子.注意在你使用SQL模式时,你不能使用=或!=:而使用LIKE或NOT LIKE比较操作符. 例如,在表pet中,为了找出以"b"开头的名字: mysql> SELECT * FROM pet WHERE name LIKE "b%"; +--

  • JAVA正则表达式及字符串的替换与分解相关知识总结

    JAVA正则表达式及字符串的替换与分解 Java 提供了 java.util.regex 包来与正则表达式进行模式匹配 java.util.regex 包主要包括以下三个类: Pattern 类: pattern 对象是一个正则表达式的编译表示.Pattern 类没有公共构造方法.要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象.该方法接受一个正则表达式作为它的第一个参数. Matcher 类: Matcher 对象是对输入字符串进行解释和匹配

  • 正则表达式之字符串模式匹配实例详解

    目录 前言 什么是正则表达式 字符范围匹配 元字符 多次重复匹配 定位匹配 贪婪模式与非贪婪模式 表达式分组 结语 前言 今天我们来学习正则表达式,正则表达式的应用十分广泛,几乎每个涉及到交互的项目都会用到的,学会正则表达式之后会让你除了提高效率外,会给你带来绝对的成就感. 接下来我们正式开始! 什么是正则表达式 正则表达式是检查.匹配字符串的表达式 正则表达式用来描述某种规则,同时它不是某种语言专有的技术,它对主流的语言都有良好的支持. 正则表达式的主要使用场景是:字符串检验,查找与替换. 示

  • 学习shell脚本之前的基础知识[图文]

    日常的linux系统管理工作中必不可少的就是shell脚本,如果不会写shell脚本,那么你就不算一个合格的管理员.目前很多单位在招聘linux系统管理员时,shell脚本的编写是必考的项目.有的单位甚至用shell脚本的编写能力来衡量这个linux系统管理员的经验是否丰富.笔者讲这些的目的只有一个,那就是让你认真对待shell脚本,从一开始就要把基础知识掌握牢固,然后要不断的练习,只要你shell脚本写的好,相信你的linux求职路就会轻松的多.笔者在这一章中并不会多么详细的介绍shell脚本

  • 正则表达式模式匹配的String方法

    在JavaScript代码中使用正则表达式进行模式匹配经常会用到String对象和RegExp对象的一些方法,例如replace.match.search等方法,以下是对一些方法使用的总结. String对象中支持正则表达式有4种方法,分别是:search.replace.match.split str.search(regexp) 定义:search()方法将在字符串str中检索与表达式regexp相匹配的字串,并且返回第一个匹配字串的第一个字符的位置.如果没有找到任何匹配的字串,则返回-1.

  • javascript正则表达式和字符串RegExp and String(一)

    前言 正则表达式是javascript非常重要和常用的功能,在jquery等大型框架中用的非常频繁,最近抽时间学习了解了相关知识,记录下来与需要的朋友分享. 思维导图 RegExp(正则表达式)的创建方式 可以通过两种方式创建一个RegExp,具体如下: 通过/-./的方式来创建正则表达式(注意: /--/两边是没有单引号或双引号的) 通过RegExp构造方法来创建一正则表达式 为了更好的描述模式,正则表达式提供了3个标识,分别是: g/i/m g: 全局匹配:在整个字符串中匹配,而不是在第一次

  • python利用正则表达式提取字符串

    前言 正则表达式的基础知识就不说了,有兴趣的可以点击这里,提取一般分两种情况,一种是提取在文本中提取单个位置的字符串,另一种是提取连续多个位置的字符串.日志分析会遇到这种情况,下面我会分别讲一下对应的方法. 一.单个位置的字符串提取 这种情况我们可以使用(.+?)这个正则表达式来提取. 举例,一个字符串"a123b",如果我们想提取ab之间的值123,可以使用findall配合正则表达式,这样会返回一个包含所以符合情况的list. 代码如下: import re str = "

  • Python 专题五 列表基础知识(二维list排序、获取下标和处理txt文本实例)

    通常测试人员或公司实习人员需要处理一些txt文本内容,而此时使用Python是比较方便的语言.它不光在爬取网上资料上方便,还在NLP自然语言处理方面拥有独到的优势.这篇文章主要简单的介绍使用Python处理txt汉字文字.二维列表排序和获取list下标.希望文章对你有所帮助或提供一些见解~ 一. list二维数组排序 功能:已经通过Python从维基百科中获取了国家的国土面积和排名信息,此时需要获取国土面积并进行排序判断世界排名是否正确. 列表基础知识 列表类型同字符串一样也是序列式的数据类型,

随机推荐