• [技术干货] python 正则表达式之匹配字符串的起始和结尾
    匹配起始:“^”匹配结尾:“$”练习:vi head.pyimport rem=re.search('The','abc The,')print(m.group())m=re.search('^The','abc The.')print(m)m=re.search('^The','The abc.')print(m.group())执行结果:[root@k8s-master-c71e ~]# python head.pyTheNoneThe[root@k8s-master-c71e ~]# vi end.pyimport rem=re.search(r'The','abc The,')print(m.group())m=re.search(r'^The$','abc The dfaksj The1')print(m.group())m=re.search('r^The$','The abc.')print(m.group())[root@k8s-master-c71e ~]# python end.pyTheNoneThe
  • [技术干货] 正则表达式
    正则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE)使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式。搜索模式可用于文本搜索和文本替换。什么是正则表达式?正则表达式是由一个字符序列形成的搜索模式。当你在文本中搜索数据时,你可以用搜索模式来描述你要查询的内容。正则表达式可以是一个简单的字符,或一个更复杂的模式。正则表达式可用于所有文本搜索和文本替换的操作。语法/正则表达式主体/修饰符(可选)其中修饰符是可选的。实例:var patt = /runoob/i实例解析:/runoob/i  是一个正则表达式。runoob  是一个正则表达式主体 (用于检索)。i  是一个修饰符 (搜索不区分大小写)。使用字符串方法在 JavaScript 中,正则表达式通常用于两个字符串方法 : search() 和 replace()。search() 方法 用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串,并返回子串的起始位置。replace() 方法 用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。search() 方法使用正则表达式实例使用正则表达式搜索 "Runoob" 字符串,且不区分大小写:var str = "Visit Runoob!"; var n = str.search(/Runoob/i);输出结果为:6search() 方法使用字符串search 方法可使用字符串作为参数。字符串参数会转换为正则表达式:实例检索字符串中 "Runoob" 的子串:var str = "Visit Runoob!"; var n = str.search("Runoob");replace() 方法使用正则表达式实例使用正则表达式且不区分大小写将字符串中的 Microsoft 替换为 Runoob :var str = document.getElementById("demo").innerHTML; var txt = str.replace(/microsoft/i,"Runoob");结果输出为:Visit Runoob!replace() 方法使用字符串replace() 方法将接收字符串作为参数:var str = document.getElementById("demo").innerHTML; var txt = str.replace("Microsoft","Runoob");
  • [技术干货] 利用正则表达式进行爬虫
    """example01 - 爬虫 - 利用正则表达式Author: AsusDate: 2021/8/16"""import reimport requestswith open('resources/豆瓣电影.html', 'r', encoding='utf-8') as file:    content = file.read()    # print(content)# re_str = '<img width="100" alt="(.*?)" src="(.+)" class="">'re_str = '<img width="100" alt="(.*?)" src="([a-z]{5}.{3}[a-z\d]{4}\.[a-z]{8}\.[a-z]{3}/view/photo/s_ratio_poster/public/p\d{9}.jpg)" class="">'result = re.search(re_str, content)print(result)# span()输出匹配到字符的起始位置和结束位置print(result.span())# group(): 将分组的内容返回出来# 如果参数是0(group(0)),将所有分组的内容输出print(result.group(1))print(result.group(2))# 将正则表达式中分组的内容合成一个元组print(result.groups())
  • [技术干货] 正则表达式
    正则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE)使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式。搜索模式可用于文本搜索和文本替换。什么是正则表达式?正则表达式是由一个字符序列形成的搜索模式。当你在文本中搜索数据时,你可以用搜索模式来描述你要查询的内容。正则表达式可以是一个简单的字符,或一个更复杂的模式。正则表达式可用于所有文本搜索和文本替换的操作。语法/正则表达式主体/修饰符(可选)其中修饰符是可选的。实例:var patt = /runoob/i实例解析:/runoob/i  是一个正则表达式。runoob  是一个正则表达式主体 (用于检索)。i  是一个修饰符 (搜索不区分大小写)。使用字符串方法在 JavaScript 中,正则表达式通常用于两个字符串方法 : search() 和 replace()。search() 方法 用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串,并返回子串的起始位置。replace() 方法 用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。search() 方法使用正则表达式实例使用正则表达式搜索 "Runoob" 字符串,且不区分大小写:var str = "Visit Runoob!"; var n = str.search(/Runoob/i);输出结果为:6search() 方法使用字符串search 方法可使用字符串作为参数。字符串参数会转换为正则表达式:实例检索字符串中 "Runoob" 的子串:var str = "Visit Runoob!"; var n = str.search("Runoob");replace() 方法使用正则表达式实例使用正则表达式且不区分大小写将字符串中的 Microsoft 替换为 Runoob :var str = document.getElementById("demo").innerHTML; var txt = str.replace(/microsoft/i,"Runoob");结果输出为:Visit Runoob!尝试一下 »replace() 方法使用字符串replace() 方法将接收字符串作为参数:var str = document.getElementById("demo").innerHTML; var txt = str.replace("Microsoft","Runoob");
  • [技术干货] 正则表达式之分组的回溯引用问题
    正则表达式简介正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。许多程序设计语言都支持利用正则表达式进行字符串操作。例如,在Perl中就内建了一个功能强大的正则表达式引擎。正则表达式这个概念最初是由Unix中的工具软件(例如sed和grep)普及开的。正则表达式通常缩写成“regex”,单数有regexp、regex,复数有regexps、regexes、regexen。引子前端开发中,难免会遇到需要匹配标签的需求,这么简单的需求,不就是两个尖括号包裹一个标签名嘛,接下来一顿操作,/<[\w]+>.*<\/[\w]+>/g,然后完美匹配了 <div>xx</div> 等内容,需求完成…等等,咋看之下,当前正则确实能匹配各种标签,但是它同样能匹配类似 <div>xx</p> 的内容。这就意味着我们需要保持两个尖括号内的内容相同才行。正则之分组回溯引用 分组 ()所谓分组,就是把要匹配的内容放在括号()里。括号里的内容可以视为是一个整体的子表达式1/<([\w]+)>.*<\/([\w]+)>/g回溯引用 \N正则表达式还提供了一种引用之前匹配分组的机制,有些时候,我们或许会寻找到一个子匹配,该匹配接下来会再次出现。1234// 该表达式中的 \1 就是整个表达式中的第一个分组var reg = /<([\w]+)>.*<\/\1>/reg.test('<div>xx</div>') // truereg.test('<div>xx</p>') // false
  • [技术干货] layui 正则表达式验证使用实例详解
    layui的正则表达式是在form表单中完成的。所以第一步要在你的html中加上指定的form 。官方参考文档:https://www.layui.com/doc/element/form.html要保证引用的layui模块中有form.js存在。快速步骤引用form.js添加form标签,并设置class属性为layui-form,不可改在要验证的属性上加lay-verify 进行验证声明layui.form 并监听提交的按钮事件 。引用js1<script src="../js/layui/layui.js" charset="utf-8"></script>主要是保证lay.modules中有form.js存在。也可以直接引用form.js添加form标签1<form class="layui-form" action="">设置要验证的属性给lay-verify赋值12<input type="text" class="input01 border" id="IdentifyId"name="IdentifyId" lay-verify="required|identity"/>系统自带的属性如下:required(必填项)phone(手机号)email(邮箱)url(网址)number(数字)date(日期)identity(身份证)自定义值如果没有想要的,可以自己写,比如自定义验证html标记验证的属性12<input type="text" lay-verify="username" placeholder="请输入用户名"><input type="password" lay-verify="pass" placeholder="请输入密码">自定义验证的规则1234567891011121314151617181920form.verify({ username: function(value, item){ //value:表单的值、item:表单的DOM对象 if(!new RegExp("^[a-zA-Z0-9_\u4e00-\u9fa5\\s·]+$").test(value)){ return '用户名不能有特殊字符'; } if(/(^\_)|(\__)|(\_+$)/.test(value)){ return '用户名首尾不能出现下划线\'_\''; } if(/^\d+\d+\d$/.test(value)){ return '用户名不能全为数字'; } }   //我们既支持上述函数式的方式,也支持下述数组的形式 //数组的两个值分别代表:[正则匹配、匹配不符时的提示文字] ,pass: [ /^[\S]{6,12}$/ ,'密码必须6到12位,且不能出现空格' ] });layui -form 使用说明1.必须要先render以后,select 才可以使用。123456789layui.use('form', function(){ var form = layui.form; //只有执行了这一步,部分表单元素才会自动修饰成功   //……   //但是,如果你的HTML是动态生成的,自动渲染就会失效 //因此你需要在相应的地方,执行下述方法来进行渲染 form.render();});提交按钮12<button type="button" class="layui-btn layui-btn-norma"lay-submit lay-filter="submit_button">确定下单</button>js自定义验证的js和提交时的操作12345678910111213layui.use('form', function(){  var form = layui.form ;  form.render();  form.verify({  payTotalAmount:[   /(^[1-9]\d*(\.\d{1,2})?$)|(^0(\.\d{1,2})?$)/   ,'请输入合适的价格'  ]   });  form.on("submit(submit_button)", function () {  onclickSearch();  });
  • [技术干货] 【技术长文】编译原理——正则表达式和有穷自动机(DFA与NFA)的关系
    NFA 和 DFA浅析—要深入了解正则表达式,必须首先理解有穷自动机。有穷自动机(Finite Automate)是用来模拟实物系统的数学模型,它包括如下五个部分:有穷状态集States输入字符集Input symbols转移函数Transitions起始状态Start state接受状态Accepting state(s)(终止状态)下图为一台有穷自动机可以看到,该自动机包含四个状态(有限状态)q0, q1, q2, q3,两个输入字符a, b,转移函数如图所示,起始状态为q0,接受状态为q3。有穷自动机,按照转移函数的不同,又可分为确定型有穷自动机(Determinism Finite Automate, DFA),与非确定型有穷自动机(Non-determinism Finite Automate, NFA)。  非确定有穷自动机容许转移函数不确定,换句话说,对任意状态,输入任意一个字符,可以转移到0个,1个或者多个状态。下图是一台非确定有穷自动机,可以看到,对状态q0输入字符a,既可以转移到q0,也可以转移到q1,这就是“非确定”的意义所在。对某个自动机来说,如果从起始状态,接受一系列输入字符,可以转移到接受状态,即认为这一系列字符可以被自动机接受。  如果两台自动机能够接受的输入字符串(或者叫做“正则语言”Regular Language)完全相同,则这两台自动机是等价的。可以证明,对于每一个非确定有穷自动机,都存在与之等价的确定型有穷自动机(证明略)。正则表达式就是建立在自动机的理论基础上的:用户写完正则表达式之后,正则引擎会按照这个表达式构建相应的自动机(可能是NFA,也可能是DFA,但它们必定是等价的),若输入一串文本之后,自动机抵达了接受状态,则这串文本可以“匹配”用户指定的正则表达式。下面是同一个正则表达式 a|ab 对应的NFA和DFA在Mastering Regular Expression中,Friedl首先分析了NFA和DFA的区别,DFA比较快,但不提供Backtrack(回溯)功能,NFA比较慢,但提供了Backtrack功能。在分析两种引擎的匹配过程时,Friedl指出,NFA是基于表达式的(Regex-Directed),而DFA是基于文本的(Text-Directed)。举例来说,对于正则表达式 to(nite|knight|night),NFA在匹配最开始两个字符(to)之后,剩下的三个组件(component)是 nite, knight 和 night,于是正则引擎会依次尝试这三个选择分支(每次尝试一个);而DFA在匹配最开始两个字符之后,会将剩下的三个选择拆分作字符,并行尝试,也就是说,匹配 to 之后,先匹配 k 或者 n ,如果 k 不能匹配,则放弃 knigth 所在的分支,再匹配 i ,再匹配 t 或 g ……这样继续下去,直到匹配结束。不幸的是,Friedl对匹配过程的分析,是完全错误的——引擎的不同,是指构建的自动机的不同,而不是匹配算法的不同!DFA引擎在任意时刻必定处于某个确定的状态,而NFA引擎可能处于一组状态之中的任何一个,所以,NFA引擎必须记录所有的可能路径(trace multiple possible routes through the NFA),NFA之所以能够提供Backtrack的功能,原因就在这里。  传统的NFA匹配算法是带回溯的深度优先搜索(backtracking depth-first search,就是上文所说的Regex-Based过程),而新的PCRE算法提供了效率更高的广度优先搜索,可以同时保持所有可能的NFA状态(请参考http://www.cl.cam.ac.uk/Teaching/current/RLFA/,尤其是Lecture Notes的section 2.2)。Friedl的错误就在这里,他混淆了应用PCRE算法的NFA与DFA的匹配过程。需 要指出的是,即使应用PCRE算法,NFA的速度仍然低于DFA,这是由NFA需要同时保存多种可能的性质决定的。从理论上说,如果我们不需要应用 Backtrack,完全可以从NFA构造出等价的DFA,再进行匹配,这样能大大提高速度——代价是,DFA需要更多的空间。转自:https://blog.csdn.net/lilongsy/article/details/82465786
  • [技术干货] 【技术长文】编译原理——词法分析器
    基本定义词法分析的第一阶段即扫描器,通常基于有限状态自动机。扫描器能够识别其所能处理的标记中可能包含的所有字符序列(单个这样的字符序列即前面所说的“语素”)。例如“整数”标记可以包含所有数字字符序列。很多情况下,根据第一个非空白字符便可以推导出该标记的类型,于是便可逐个处理之后的字符,直到出现不属于该类型标记字符集中的字符(即最长一致原则)。词法分析器的工作是低级别的分析:将字符或者字符序列转化成记号。在谈论词法分析时,使用术语“词法记号”(简称记号)、“模式”和“词法单元”表示特定的含义。在分析时,一是把词法分析器当成语法分析的一部分,另一种是把词法分析器当成编译程序的独立部分。在前一种情况下,词法分析器不断地被语法分析器调用,每调用一次词法分析器将从源程序的字符序列拼出一个单词,并将其Token值返回给语法分析器。后一种情况则不同,词法分析器不是被语法分析器不断地调用,而是一次扫描全部单词完成编译器的独立一遍任务。制作一个简单的词法分析器定义如下:(1)保留字int   void   if   else   return   while   正则表达式即为原串,在代码中当作标识符匹配,匹配完后再与保留字比较(2)标识符letter = [a-z | A-Z]digit = [0-9]正则表达式 letter (letter | digit )*(3)数字digit = [1-9]D = 0 | digit整型:正则表达式:digit D*浮点型:正则表达式:digit (. D*)? (e -? digit D*)?(4)符号+   -   *   /   %   >   >=   <   <=   [   ]   (   )   {   }   !=   ==    ,    ;正则表达式即符号本身(5)注释C = 所有字符//型:正则表达式:// C*/**/型:正则表达式:/* C* */代码实现:  父类:class Scanner { private: std::string buffer; int pos; //缓冲区位置 int syn; //token类别 int state; //DFA中的状态 std::string sourcename; int filepos; std::ifstream infile; //int tsss; const int BUFFERLENGTH = 4096; public: Scanner(const char* s) { sourcename = s; infile.open(s); pos = 0; syn = -1; state = 0; filepos = 0; } void GetToken(); //在DFA上转移,识别token bool IsNum(const char c); bool IsLetter(const char c); char GetNext(); //获取下一个字符 void Back(); //向前看完后回溯 ~Scanner() { infile.close(); } };    子类:oid Scanner::GetToken()      代码过多,不予以全部展示 bool Scanner::IsNum(const char c) bool Scanner::IsLetter(const char c) char Scanner::GetNext() void Scanner::Back()测试用例:int gcd (int u, int v) { if (v == 0) return u ; else return gcd(v,u-u/v*v); } void main(void) { int x; int y; x = input(); y = input(); output(gcd(x,y)); }测试结果:
  • [技术干货] 从字符串中取出特定的某个字符串(使用正则表达式获取)
        //定义字符串var str1 = '# abc 1234we # abc 456we # abc 789qwe'//正则表达式,获取str1字符串中1234we,456we,789qwevar key = /abc (.\d\s\w\-_)///执行正则表达式content = content.match(key)
  • Jmeter系列(27)- 详解正则提取器
    有了 JSON 提取器为啥还要用正则提取器?JSON 提取器只针对接口返回的响应内容如果想提取的是响应头、请求头的值,而非响应内容的值呢?这个时候正则提取器的作用就出来了,它可以提取请求任一部分的值 需知正则表达式很多内容,在这篇文章中不会展开详细说的哦,主要还是说提取器的使用 正则提取器我们通过实际栗子去讲述理论知识点 正则提取器界面介绍 字段含义字段含义Apply to应用范围,选默认的 main sample only 就行了Field to check可提取的字段Names of created variables接收提取值的变量名必传Regular Expression正则表达式Template从找到的匹配项中创建字符串的模板Match No.(0 for Random)取第几个值0:随机,默认-1:所有1:第一个值非必传Default Value缺省值,匹配不到值的时候取该值非必传Use empty default value勾选后,提取不到值时,则返回空字符串 Template如果一条正则表达式有多个提取结果,则提取结果是数组形式模板 $1$、$2$.....表示把解析到的第几个值赋给变量,从 1 开始匹配$0$ 表示整个表达式匹配的内容(后续具体看栗子)若只有一个结果,只能是$1$ Field to check属性含义Body响应体,不包括响应头;最常用Body (unescaped)响应体,替换了所有HTML转义符;不建议使用Body as a Document从不同类型的文件中提取文本;影响性能Request Headers请求头Response Headers响应头URLURLResponse Code响应码Response Message响应信息 Body Request Headers Response Headers URL Response Code、Message 入门栗子栗子的前提这个栗子,我都会以这个地址的接口来完成 JSON 提取器的实战栗子,大家可以注册个账号玩一玩哦 测试计划树结构下面多个栗子都以这个测试计划为基础哦 提取某个特定的值的栗子登录接口响应登录是执行其他接口的前置接口,所以要获取用户登录后的 token、uuid 提取 token 提取 uuid 其他接口调用 token、uuid 知识点提其他接口可以通过  ${var}  这种格式,来获取提取到的值 ( ) 里面写匹配规则,用于解析正则表达式 .*? 表示匹配任意长度的任意字符,这也是最常用的正则表达式一般 (.+?) 和 (.*?) 能够满足我们 80%的使用场景 一般正则表达式都可以写成下面两种 左边界(.+?)右边界  左边界(.*?)右边界  举更多栗子前的一些话上面讲的是使用正则提取器时的一个流程,也是实际工作中最简单的栗子在实际项目中,我们可能会出现一条正则表达式有多个提取结果的情况 JSON 字符串下面的栗子都以这个 JSON 字符串为基础,从里面提取结果这 JSON 字符串也是某个接口的响应内容,货真价实,感兴趣也可以自己玩一玩:http://api.yesapi.cn/docs-api-App.User.GetList.html{ "ret": 200, "msg": "V2.5.1 YesApi App.User.GetList", "data": { "total": 4, "err_msg": "", "err_code": 0, "users": [ { "role": "user", "status_desc": "正常", "reg_time": "2020-06-22 20:45:05", "role_desc": "普通会员", "ext_info": { "yesapi_nickname": "", "yesapi_points": 0 }, "uuid": "0564CE592B4CE914365D8922F6FC4CEC", "username": "luojunjiess286", "status": 0 }, { "role": "user", "status_desc": "正常", "reg_time": "2020-06-22 14:27:17", "role_desc": "普通会员", "ext_info": { "yesapi_nickname": "", "yesapi_points": 0 }, "uuid": "0164DC0680F84DCE40D3DD4A36640ECA", "username": "luojunjiessa", "status": 0 }, { "role": "admin", "status_desc": "正常", "reg_time": "2020-03-23 22:48:32", "role_desc": "管理员", "ext_info": { "yesapi_nickname": "", "yesapi_points": 0 "yesapi_reg_source": "" }, "uuid": "079BF6BB82AFCFC7084F96AECAF0519F", "username": "luojunjiess", "status": 0 } ] } } 一条正则表达式只有一个提取结果的栗子什么叫只有一个提取结果就是正则表达式里只有一个 ( ) ,且  Match No. 不是 -1 未填写模板提取器 测试结果uuid1= uuid1_g=1 uuid1_g0="uuid":"0564CE592B4CE914365D8922F6FC4CEC" uuid1_g1=0564CE592B4CE914365D8922F6FC4CEC 知识点如果正则匹配到值,但是没有填模板,则返回空 $0$提取器 测试结果uuid2="uuid":"0564CE592B4CE914365D8922F6FC4CEC" uuid2_g=1 uuid2_g0="uuid":"0564CE592B4CE914365D8922F6FC4CEC" uuid2_g1=0564CE592B4CE914365D8922F6FC4CEC 知识点 $0$ 模板其实返回的就是 uuid2_g0 的值返回了整个正则表达式,不只是 ( ) 内匹配到的值 $1$提取器 测试结果uuid3=0564CE592B4CE914365D8922F6FC4CEC uuid3_g=1 uuid3_g0="uuid":"0564CE592B4CE914365D8922F6FC4CEC" uuid3_g1=0564CE592B4CE914365D8922F6FC4CEC 知识点 $1$  模板其实返回的就是 uuid2_g1 的值仅返回 ( ) 内匹配到的值 $2$提取器 测试结果uuid4=null uuid4_g=1 uuid4_g0="uuid":"0564CE592B4CE914365D8922F6FC4CEC" uuid4_g1=0564CE592B4CE914365D8922F6FC4CEC 知识点 $2$ 模板并不存在,其实就是 uuid4_g2 变量不存在,即使勾了使用空默认值,也返回 null, 总结其实 uuid 在 JSON 字符串中有三个可匹配到的值,如果不填写匹配数字 Match No. ,则会随机取一个 uuid 并返回像上述的几个栗子,都填了 1 ,所以都返回了第一个匹配到的 uuid 一条正则表达式有多个提取结果的栗子什么叫有多个提取结果有两种情况一条表达式有多个 ( ) 一个 ( ) 匹配到多个值,且 Match No 填了 -1 一个 ( ) 匹配到多个值 提取器 测试结果手动分成四部分uuid1_1=0564CE592B4CE914365D8922F6FC4CEC uuid1_1_g=1 uuid1_1_g0="uuid":"0564CE592B4CE914365D8922F6FC4CEC" uuid1_1_g1=0564CE592B4CE914365D8922F6FC4CEC uuid1_2=0164DC0680F84DCE40D3DD4A36640ECA uuid1_2_g=1 uuid1_2_g0="uuid":"0164DC0680F84DCE40D3DD4A36640ECA" uuid1_2_g1=0164DC0680F84DCE40D3DD4A36640ECA uuid1_3=079BF6BB82AFCFC7084F96AECAF0519F uuid1_3_g=1 uuid1_3_g0="uuid":"079BF6BB82AFCFC7084F96AECAF0519F" uuid1_3_g1=079BF6BB82AFCFC7084F96AECAF0519F uuid1_matchNr=3 知识点一个 ( ) 匹配到多个值的场景 ,一般会结合 ForEach控制器,可以循环将提取到的值赋予到 HTTP 请求中可以看看下图的小栗子,这里不展开讲,后面会再详细讲解 结构树 + ForEach 控制器 查看结果树 一条表达式有多个( ),且模板为空提取器 测试结果info1= info1_g=2 info1_g0="uuid":"0564CE592B4CE914365D8922F6FC4CEC","username":"luojunjiess286" info1_g1=0564CE592B4CE914365D8922F6FC4CEC info1_g2=luojunjiess286 一条表达式有多个( ),且只有一个模板提取器 测试结果info2=0564CE592B4CE914365D8922F6FC4CEC info2_g=2 info2_g0="uuid":"0564CE592B4CE914365D8922F6FC4CEC","username":"luojunjiess286" info2_g1=0564CE592B4CE914365D8922F6FC4CEC info2_g2=luojunjiess286 知识点info2 拿的就是 info2_g1 的值 $1$ 获取的是第一个 ( ) 匹配到的值, $2$ 获取的是第二个 ( ) 匹配到的值,以此类推      一条表达式有多个( ),且有两个模板提取器 测试结果info3=0564CE592B4CE914365D8922F6FC4CECluojunjiess286 info3_g=2 info3_g0="uuid":"0564CE592B4CE914365D8922F6FC4CEC","username":"luojunjiess286" info3_g1=0564CE592B4CE914365D8922F6FC4CEC info3_g2=luojunjiess286 info4=0564CE592B4CE914365D8922F6FC4CEC,luojunjiess286 info4_g=2 info4_g0="uuid":"0564CE592B4CE914365D8922F6FC4CEC","username":"luojunjiess286" info4_g1=0564CE592B4CE914365D8922F6FC4CEC info4_g2=luojunjiess286 
  • [技术干货] java干活分享之正则表达式
    用途:正则表达式用来定义字符串模式、还可以用来搜索 编辑 处理文本。什么是正则表达式呢?其实一个字符串就是一个简单的正则表达式  如:hello java 匹配到的正则表达式就”hello java“  那就有人问了 特殊符号例如 点号 .  也是正则表达式么?回答是对的点号匹配到的字符 如 "a" 或"1"举例: this is java 匹配字符串 "this is java"            this\s+is\s+java 注意字符串中的\s+ 匹配单词this后面的\s可以匹配多个空格 之后匹配is字符串 在之后\s匹配多个空格然后在跟上java字符串            匹配结果:this is java           ^\d+(\.\d+)?  ^定义了以什么开始  \d匹配一个或多个数字 ?设置括号内的选项是可选的  \匹配""  可以匹配的例子:  "5","1.5","3.8"学过perl的都知道其实java 的正则表达式和perl是最为相似的java util regex包主要包括以下三个类:pattern类:              作用:pattern对象是一个正则表达式的编译。pattern类没有公共的构造方法 要创建一个pattern对象 必须先调用其公共静态编译方法 它返回一个pattern对象 该方法接受一个正则表达式的参数matcher类:             作用:matcher对象是对输入字符串进行解释和匹配操作的引擎 与pattern类一样 matcher也没有公共的构造方法  需要调用pattern对象的matcher方法获得一个matcher对象patternsyntaxexception            作用:其是一个非强制的异常类  它表示一个正则表达式模式中的语法错误举个例子吧:学过正则表达式的知道名词:捕捉组捕捉组是把多个字符当一个单独的单元进行处理的方法它提供对括号内的字符分组来创建例如:正则表达式(cat)创建了一个单一分组  组内包含:"d"  "o"  "g"捕捉组通过从左至右计算其开括号来编号例如 ((A)(B)(C))有这样四个分组:(A)  ((A)(B)(C)) )(B)(C)  (C)  可以通过调用matcher对象的groupcount 方法来查看表达式到底分了多少组  groupcount 方法返回一个int值  表示matcher对象当前有多个捕捉组还有一个特殊的组group(0) 它总是代表整个表达式 该组不包括在groupcount的返回值中举个实例:正则表达式语法:在其他语言中,\\表示我想要在这边负责vu挨打事故这个i部分插入一个普通的反斜杠 请不要给他任何特殊的意义;(其实就是c语言中的转义字符)在java中\\表示我要插入一个正则表达式的反斜杠,所以后面的字符有特殊的意义所以在其他的语言中 如 c  pert  一个反斜杠就足以具有转义的作用 而在java中正则表达式中则需要有俩个反斜杠菜鸟被解析为其他语言中的转义作用。这就是为什么表示一位数字的正则表达式是\\d而 表示一个普通的反斜杠是\\\\索引方法:pubilc int start()  返回以前匹配的初始索引public int start(int group) 返回在以前的匹配操作期间 由给定组所捕获的子序列的初始索引public int end()返回最后匹配字符之后的偏移量public int end(int group) 返回在以前的匹配操作期间由给定组所捕获子序列的最后字符之后的偏移量举例:那第三期的java之正则表达式就到此结束啦~喜欢的小伙伴点赞加收藏~
  • [技术干货] 如何使用正则匹配最后一个字符串详解
    前几天遇到一个需求,输入的是123456789<user>    <user>        <name>a</name>    </user>    <user>        <name>a</name>    </user></user><password>123</password>要求拿到12345678<user>    <user>        <name>a</name>    </user>    <user>        <name>a</name>    </user></user>也就是去掉最后一个</user>后面的字符串。方法有很多,我首先想到的是用正则匹配去掉</user>后面的字符串。最后写出来的表达式是(?<=</user>)(?![\w\W]*</user>)[\w\W]+。首先用(?<=</user>)匹配所有前面是</user>的位置,如图,总共有三个位置。这里我们正则表达式(?<=</user>)的意思就是匹配的位置之前的字符串是</user>,也就是我们匹配到的位置在</user>之后。这里用到了正则表达式语法中的断言,有的书上也称该语法为预查或者环视,都是一样的用法。有如下语法:(?=pattern) 零宽正向先行断言 (?!pattern) 零宽负向先行断言 (?<=pattern) 零宽正向后行断言 (?<!pattern) 零宽负向后行断言这里用到的是(?<=pattern),零宽表示它匹配的是在字符串中的位置,如同^匹配字符串串首,$匹配字符串串尾。正向代表它必须满足pattern。后行代表它匹配的位置在pattern之后。其次,再这三个位置上进行筛选,能够看出这三个位置的区别是后面是否有</user>,如果没有的话那么它就是最后一个</user>后面的位置。在之前的表达式后面添上(?![\w\W]*?</user>)此时表达式变为(?<=</user>)(?![\w\W]*?</user>)。最后,在之前的正则表达式后面加上[\w\W]+贪婪匹配即尽可能多的匹配该位置后面的字符串。最终的正则表达式是(?<=</user>)(?![\w\W]*?</user>)[\w\W]*最后的最后用四张图简单地描述四种断言的不同之处。这里输入的字符串都是123456。(?=3),它匹配的位置是后面的字符为3的位置。 (?<=3),它匹配的位置是前面的字符为3的位置。 (?!3)匹配的位置是后面的字符不为3的位置,可以看到箭头所指的地方没有被匹配到,其他位置都被匹配到了。(?<!3)匹配的位置是前面的字符不为3的位置,可以看到箭头所指的地方没有被匹配到,其他位置都被匹配到了。能够看到得到了最后一个匹配结果。这里的正则表达式(?!pattern) 是零宽负向先行断言,也就是它会往后匹配pattern,匹配到的位置在pattern之前,并且匹配到的字符串必须不满足pattern。(?![\w\W]*?</user>)的意思是在匹配到的位置后面必须不是[\w\W]*?</user>,\w匹配的是[a-zA-Z0-9_]即匹配字母数字和下划线,而\W匹配的是[^a-zA-Z0-9_]即不是字母数字也不是下划线的字符,同时匹配这两个就相当于匹配任意字符。[\w\W]后面的*代表匹配0-任意多次,后面的?代表懒惰模式,即只要满足条件就立即返回。
  • [SQL] GaussDB(DWS)的正则表达式知多少
    【摘要】 GaussDB(DWS)除了支持标准的POSIX正则表达式句法,还拥有一些特殊句法和选项,这些你可了解?本文便为你讲解这些特殊句法和选项。概述正则表达式(Regular Expression,简称RE),通常被用来检索、替换那些符合某个模式(规则)的文本。正则表达式使用比较灵活,功能强大,因此经常被用到进行文本的搜索和替换中,帮助开发人员快速进行批量文本查询和处理。比如常用的linux的grep命令,许多程序设计语言比如Perl、Tcl也都支持正则表达式进行字符串操作。GaussDB(DWS)支持的正则表达式POSIX 1003.2中定义的正则表达式RE有两种形式:扩展RE或ERE(大致为egrep的RE),和基本RE或BRE(大致为ed的RE),GaussDB(DWS)都支持这两种形式,并实现了在编程语言(如Perl和Tcl)中广泛使用而POSIX标准中未包含的一些扩展。使用这些非POSIX扩展的RE在本文中称为高级RE或ARE。ARE几乎是ERE的超集,但是BRE有几种符号不相容性(而且是有限的)。GaussDB(DWS)的正则表达式的主要句法和在其他程序语言中支持的句法功能相同,此文不再赘述。本文中对GaussDB(DWS)拥有的特殊形式和句法进行说明。GuassDB(DWS)支持的正则表达式函数GaussDB(DWS)提供了支持POSIX正则表达式的函数,如表1所示。表1  GaussDB(DWS)中的正则表达式函数函数返回类型描述参数说明regexp_replace(string text, pattern text, replacement text [, flags text])Text提供了将匹配POSIX正则表达式模式的子串替换为新文本的功能string:待处理的源字符串pattern:一个正则表达式REreplacement:用此字符串替换原字符串中匹配的部分flags:可选参数,具体取值参见表2regexp_matches(string text, pattern text [, flags text])setof text[]返回一个文本数组,该数组由匹配一个POSIX正则表达式模式得到的所有被捕获子串构成regexp_split_to_table(string text, pattern text [, flags text])setof text把一个POSIX正则表达式模式当作一个定界符来分离一个串regexp_split_to_array(string text, pattern text [, flags text ])text[]和regexp_split_to_table类似,是一个正则表达式分离函数,不过它的结果以一个text数组的形式返回从表1中看到,GuassDB(DWS)支持的正则表达式函数都有一个可选的flags参数,该参数的可选项及其含义是什么呢?下面将展开进行详细举例说明。GaussDB(DWS)正则表达式函数的flags参数详解表2中列举了表1中flags参数的所有可选项。表2  GaussDB(DWS)正则表达式函数的flags参数的选项说明选项描述bRE是一个BRE,表示按照BRE匹配模式的规则进行匹配c大小写敏感匹配 (是一个可被覆盖的操作符类型)g表示替换每一个匹配的子字符串而不仅仅是第一个。默认仅替换第一个匹配的子字符串i大小写不敏感匹配(是一个可被覆盖的操作符类型)m和选项n同义n换行敏感匹配,此选项生效时,换行符影响元字符(.、^、$和[^)的匹配p部分换行敏感匹配,此选项生效时,换行符影响元字符(.和[^)的匹配。部分是相对选项n而言qRE被认为是加双引号的文本字符串,所有字符都是普通字符s非换行敏感匹配(默认),与n相对t紧凑语法(默认)w反部分换行敏感匹配,此选项生效时,换行符影响元字符(^和$)的匹配。部分是相对选项n而言x扩展语法表2中给出的flags参数选项描述,非常简洁,理解起来比较困难。下面通过一些示例,来直观帮助理解上面这些flags参数选项的含义。g选项示例1-1:未指定’g‘选项,仅对第一个匹配项进行替换示例1-2:指定’g‘选项,对所有匹配项进行替换c 和 i 选项示例2-1:默认情况下,进行大小写敏感匹配示例2-2:显示指定进行大小写敏感匹配示例2-3:显示指定进行大小写不敏感匹配 n[或m]、s、p、w选项对元字符点(.)的影响示例3-1:指定选项n时,元字符点(.)不匹配换行符示例3-2:指定选项s时,元字符点(.)匹配换行符示例3-3:指定选项p时,元字符点(.)不匹配换行符示例4-4:指定选项w时,元字符点(.)匹配换行符n[或m]、s、p、w选项对元字符^、$的影响示例5-1:指定选项n时,元字符点^、$匹配行首和行尾示例5-2:指定选项s时,元字符点^、$不匹配行首和行尾示例5-3:指定选项p时,元字符点^、$不匹配行首和行尾示例5-4:指定选项w时,元字符点^、$匹配第一个行首匹配的行到最后一个行尾匹配的行 n[或m]、s、p、w选项对元字符 [^ 的影响示例6-1:指定选项n时,换行符不匹配被[^排除的字符,所有行尾的换行符未被替换为M示例6-2:指定选项s时,换行符匹配被[^排除的字符,所有行尾的换行符被替换为M示例6-3:指定选项p时,换行符不匹配被[^排除的字符,所有行尾的换行符被替换为M示例6-4:指定选项w时,换行符匹配被[^排除的字符,所有行尾的换行符被替换为M t 和 x 选项通常情况下,RE语法都是严格的,即RE中的所有字符都是重要的。严格语法是默认的,也可以通过指定选项t表示。示例6-1:在严格语法中,空白字符也是重要的GaussDB(DWS)还有一个扩展语法,通过指定x选项表示。在扩展语法中,RE中的空白字符(在这里,空白是空格、水平制表符、新行、和任何属于space字符类的字符。)将被忽略,以及#和换行符(或RE的结尾)之间的所有字符也将被忽略。这种语法允许对复杂的RE进行分段落和注释。示例6-2:在扩展语法中,RE中的空格被忽略该规则有三个例外:转义字符\后的空白或#被保留示例6-3括号表达式中的空白或#被保留示例6-4空白和注释不能出现多字符符号中。在 ARE 里,方括弧表达式外面,序列(?#ttt) (这里的ttt是任意不包含)的文本)是一个注释,完全被忽略。示例6-5:空格出现在多字符符号中示例6-6:注释出现在多字符符号中当flags中指定了多个有相反含义的选项时,则后出现的选项覆盖前面出现的选项示例7-1:后出现的s选项覆盖了n选项示例7-2:后出现的n选项覆盖了s选项GaussDB(DWS)正则表达式的特殊句法两个特殊的前缀:***: 和***=一个RE可以以两个特殊的前缀中的某一个开头。RE以***:开头RE以***:开头,则剩余的RE被当作一个ARE。(在GaussDB(DWS)中,这通常没有作用,因为RE被假定为ARE;但是,如果正则表达式函数的flags参数指定了ERE或BRE模式,那么它就会起作用。)示例8-1:在BRE匹配模式中(regexp_replace函数的最后一个参数中指定的字母‘b’即表示使用BRE匹配模式),正则表达式中要表示圆括号表达式,需要将圆括号进行转义;同样,表示原子精确次数匹配序列的花括号,也需要进行转义示例8-2:增加***: 前缀后,即使指定了使用BRE匹配模式,也是按照ARE的匹配模式的规则进行匹配RE以***=开头RE以***=开头,则RE的其余部分被认为是一个字面字符串,所有字符都被认为是普通字符。示例9-1:‘|’在ARE匹配模式的正则表达式中是代表或含义的元字符示例9-2:代表或含义的元字符‘|’,在以***=为前缀的正则表达式中,失去其元字符的特殊含义,被看作字符串中的普通字符嵌套选项ARE可以以嵌套选项开头:序列(?xyz) (其中xyz是一个或多个字母字符)指定影响RE其余部分的选项。这些选项覆盖任何先前确定的选项,特别是,它们可以覆盖由正则表达式运算符或正则表达式函数的flags参数隐含的大小写敏感行为。可选择的字母如表2所示中除’g’选项外的其他选项。示例10-1:不含嵌套选项的大小写不敏感匹配示例10-2:嵌套选项中的大小写敏感覆盖flags中的大小写不敏感匹配结语通过上面丰富的示例,深入了解了GaussDB(DWS)正则表达式的特殊句法和flags选项含义,在使用GaussDB(DWS)正则表达式函数时便可以得心应手。原文链接:https://bbs.huaweicloud.com/blogs/242030【推荐阅读】【最新活动汇总】DWS活动火热进行中,互动好礼送不停(持续更新中)  HOT  【博文汇总】GaussDB(DWS)博文汇总1,欢迎大家交流探讨~(持续更新中)【维护宝典汇总】GaussDB(DWS)维护宝典汇总贴1,欢迎大家交流探讨(持续更新中)【项目实践汇总】GaussDB(DWS)项目实践汇总贴,欢迎大家交流探讨(持续更新中)【DevRun直播汇总】GaussDB(DWS)黑科技直播汇总,欢迎大家交流学习(持续更新中)【培训视频汇总】GaussDB(DWS) 培训视频汇总,欢迎大家交流学习(持续更新中)扫码关注我哦,我在这里↓↓↓
  • [技术干货] python re模块和正则表达式(下)
    3、数字匹配1、 匹配一段文本中的每行的邮箱http://blog.csdn.net/make164492212/article/details/516566382、 匹配一段文本中的每行的时间字符串,比如:‘1990-07-12';分别取出1年的12个月(^(0?[1-9]|1[0-2])$)、一个月的31天:^((0?[1-9])|((1|2)[0-9])|30|31)$3、 匹配qq号。(QQ号从10000开始) [1,9][0,9]{4,}4、 匹配一个浮点数。 ^(-?\d+)(\.\d+)?$ 或者 -?\d+\.?\d*5、 匹配汉字。 ^[\u4e00-\u9fa5]{0,}$6、 匹配出所有整数4、爬虫123456789101112131415161718192021222324252627282930313233343536373839404142import requests import reimport json def getPage(url):   response=requests.get(url)  return response.text def parsePage(s):     com=re.compile('<div class="item">.*?<div class="pic">.*?<em .*?>(?P<id>\d+).*?<span class="title">(?P<title>.*?)</span>'          '.*?<span class="rating_num" .*?>(?P<rating_num>.*?)</span>.*?<span>(?P<comment_num>.*?)评价</span>',re.S)   ret=com.finditer(s)  for i in ret:    yield {      "id":i.group("id"),      "title":i.group("title"),      "rating_num":i.group("rating_num"),      "comment_num":i.group("comment_num"),    } def main(num):   url='https://movie.douban.com/top250?start=%s&filter='%num  response_html=getPage(url)  ret=parsePage(response_html)  print(ret)  f=open("move_info7","a",encoding="utf8")   for obj in ret:    print(obj)    data=json.dumps(obj,ensure_ascii=False)    f.write(data+"\n") if __name__ == '__main__':  count=0  for i in range(10):    main(count)    count+=25简化版123456789101112131415161718192021222324252627282930313233343536373839import reimport jsonfrom urllib.request import urlopen def getPage(url):  response = urlopen(url)  return response.read().decode('utf-8') def parsePage(s):  com = re.compile(    '<div class="item">.*?<div class="pic">.*?<em .*?>(?P<id>\d+).*?<span class="title">(?P<title>.*?)</span>'    '.*?<span class="rating_num" .*?>(?P<rating_num>.*?)</span>.*?<span>(?P<comment_num>.*?)评价</span>', re.S)   ret = com.finditer(s)  for i in ret:    yield {      "id": i.group("id"),      "title": i.group("title"),      "rating_num": i.group("rating_num"),      "comment_num": i.group("comment_num"),    }  def main(num):  url = 'https://movie.douban.com/top250?start=%s&filter=' % num  response_html = getPage(url)  ret = parsePage(response_html)  print(ret)  f = open("move_info7", "a", encoding="utf8")   for obj in ret:    print(obj)    data = str(obj)    f.write(data + "\n") count = 0for i in range(10):  main(count)  count += 25flags有很多可选值:re.I(IGNORECASE)忽略大小写,括号内是完整的写法re.M(MULTILINE)多行模式,改变^和$的行为re.S(DOTALL)点可以匹配任意字符,包括换行符re.L(LOCALE)做本地化识别的匹配,表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境,不推荐使用re.U(UNICODE) 使用\w \W \s \S \d \D使用取决于unicode定义的字符属性。在python3中默认使用该flagre.X(VERBOSE)冗长模式,该模式下pattern字符串可以是多行的,忽略空白字符,并可以添加注释实现能计算类似1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式的计算器程序
  • [技术干货] python re模块和正则表达式
    2.4 字符集[][^]正则待匹配字符匹配结果说明小[明李子巧玲珑]*小明和小李子和小巧玲珑小明小李子小巧玲珑表示匹配"小"字后面[明李子巧玲珑]的字符任意次小[^和]*小明和小李子和小巧玲珑小明小李子小巧玲珑表示匹配一个不是"和"的字符任意次[\d]456bdha34563表示匹配任意一个数字,匹配到4个结果[\d]+456bdha34563表示匹配任意个数字,匹配到2个结果2.5 分组 ()与 或 |[^]身份证号码是一个长度为15或18个字符的字符串,如果是15位则全部由数字组成,首位不能为0;如果是18位,则前17位全部是数字,末位可能是数字或x,下面我们尝试用正则来表示:正则待匹配字符匹配结果说明^[1-9]\d{13,16}[0-9x]$110101198001017032110101198001017032表示可以匹配一个正确的身份证号^[1-9]\d{13,16}[0-9x]$11010119800101701101011980010170表示也可以匹配这串数字,但这并不是一个正确的身份证号码,它是一个16位的数字^[1-9]\d{14}(\d{2}[0-9x])?$1101011980010170False现在不会匹配错误的身份证号了()表示分组,将\d{2}[0-9x]分成一组,就可以整体约束他们出现的次数为0-1次^([1-9]\d{16}[0-9x]|[1-9]\d{14})$110105199812067023110105199812067023表示先匹配[1-9]\d{16}[0-9x]如果没有匹配上就匹配[1-9]\d{14}2.6 转义符 \在正则表达式中,有很多有特殊意义的是元字符,比如\d和\s等,如果要在正则中匹配正常的"\d"而不是"数字"就需要对"\"进行转义,变成'\\'。在python中,无论是正则表达式,还是待匹配的内容,都是以字符串的形式出现的,在字符串中\也有特殊的含义,本身还需要转义。所以如果匹配一次"\d",字符串中要写成'\\d',那么正则里就要写成"\\\\d",这样就太麻烦了。这个时候我们就用到了r'\d'这个概念,此时的正则是r'\\d'就可以了。正则待匹配字符匹配结果说明\d\dFalse因为在正则表达式中\是有特殊意义的字符,所以要匹配\d本身,用表达式\d无法匹配\\d\dTrue转义\之后变成\\,即可匹配"\\\\d"'\\d'True如果在python中,字符串中的'\'也需要转义,所以每一个字符串'\'又需要转义一次r'\\d'r'\d'True在字符串之前加r,让整个字符串不转义2.7 贪婪匹配贪婪匹配:在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪匹配正则待匹配字符匹配结果说明<.*><script>...<script><script>...<script>默认为贪婪匹配模式,会匹配尽量长的字符串<.*?>r'\d'<script><script>加上?为将贪婪匹配模式转为非贪婪匹配模式,会匹配尽量短的字符串几个常用的非贪婪匹配*? 重复任意次,但尽可能少重复+? 重复1次或更多次,但尽可能少重复?? 重复0次或1次,但尽可能少重复{n,m}? 重复n到m次,但尽可能少重复{n,}? 重复n次以上,但尽可能少重复.*?的用法. 是任意字符* 是取 0 至 无限长度? 是非贪婪模式,何在一起就是 取尽量少的任意字符,一般不会这么单独写,他大多用在:.*?x 就是取前面任意长度的字符,直到一个x出现三、re模块123456789101112131415161718192021222324252627282930313233import re ret = re.findall('a', 'ea eg an') # 返回所有满足匹配条件的结果,放在列表里print(ret) #结果 : ['a', 'a'] ret = re.search('a', 'va eg an').group()print(ret) #结果 : 'a'# 函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以# 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。 ret = re.match('a', 'abc').group() # 同search,不过尽在字符串开始处进行匹配print(ret)#结果 : 'a' ret = re.split('[ab]', 'abcd') # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割print(ret) # ['', '', 'cd'] ret = re.sub('\d', 'H', 'va3eg4an4', 1)#将数字替换成'H',参数1表示只替换1个print(ret) #vaHeg4an4 ret = re.subn('\d', 'H', 'va3eg4an4')#将数字替换成'H',返回元组(替换的结果,替换了多少次)print(ret) obj = re.compile('\d{3}') #将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字ret = obj.search('abc123eeee') #正则表达式对象调用search,参数为待匹配的字符串print(ret.group()) #结果 : 123 import reret = re.finditer('\d', 'ds3sy4784a')  #finditer返回一个存放匹配结果的迭代器print(ret) # <callable_iterator object at 0x10195f940>print(next(ret).group()) #查看第一个结果print(next(ret).group()) #查看第二个结果print([i.group() for i in ret]) #查看剩余的左右结果注意:1 findall的优先级查询:1234567import re ret = re.findall('www.(baidu|xunlei).com', 'www.xunlei.com')print(ret) # ['xunlei']   这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可 ret = re.findall('www.(?:baidu|xunlei).com', 'www.xunlei.com')print(ret) # ['www.xunlei.com']2 split的优先级查询123456789ret=re.split("\d+","va3eg4an")print(ret) #结果 : ['va', 'eg', 'an'] ret=re.split("(\d+)","va3eg4an")print(ret) #结果 : ['va', '3', 'eg', '4', 'an'] #在匹配部分加上()之后所切出的结果是不同的,#没有()的没有保留所匹配的项,但是有()的却能够保留了匹配的项,#这个在某些需要保留匹配部分的使用过程是非常重要的。3.1 匹配标签12345678910111213import re ret = re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>")#还可以在分组中利用?<name>的形式给分组起名字#获取的匹配结果可以直接用group('名字')拿到对应的值print(ret.group('tag_name')) #结果 :h1print(ret.group()) #结果 :<h1>hello</h1> ret = re.search(r"<(\w+)>\w+</\1>","<h1>hello</h1>")#如果不给组起名字,也可以用\序号来找到对应的组,表示要找的内容和前面的组内容一致#获取的匹配结果可以直接用group(序号)拿到对应的值print(ret.group(1))print(ret.group()) #结果 :<h1>hello</h1>2、匹配整数12345678import re ret=re.findall(r"\d+","1-2*(60+(-40.35/5)-(-4*3))")print(ret) #['1', '2', '60', '40', '35', '5', '4', '3']ret=re.findall(r"-?\d+\.\d*|(-?\d+)","1-2*(60+(-40.35/5)-(-4*3))")print(ret) #['1', '-2', '60', '', '5', '-4', '3']ret.remove("")print(ret) #['1', '-2', '60', '5', '-4', '3']
总条数:54 到第
上滑加载中