今天朋友问我一个问题,是这样子的,通过正则表达式匹配html标签input包含hidden的字符串,具体如下:

[java] view plain copy
  1. "<input type=\"hidden\" id=\"xxx\" name=\"xxx\" value=\"xxx\" /><input type=\"text\" id=\"xxx\" name=\"xxx\" value=\"xxx\" />"

匹配下来,应该输出:

[java] view plain copy
  1. "<input type=\"hidden\" id=\"xxx\" name=\"xxx\" value=\"xxx\" />"

读了这个问题之后,觉得挺简单的,直接利用基本的语法包含头<input   尾 /> 还有hidden 不就OK了么?于是写出了下面的正则表达式:

[java] view plain copy
  1. "<input.*?hidden.*?/>"

恩,不错,符合基本的题意,而且运行结果正确,可随意想到要是那个hidden在后面那个input中是什么结果呢?于是测试发现结果如下:

[java] view plain copy
  1. <input type="text" id="xxx" name="xxx" value="xxx" /><input type="hidden" id="xxx" name="xxx" value="xxx" />

都输出了,这是神马情况啊,仔细分析了下,在匹配过程中在第一个inpu中没有找到hidden,但是第二中找到了,接着一直往后匹配,ok,匹配结束,输出结果如上。

哦,那是否可以去判断结束符号/>,即结果中不包含/>,所以立即想到了(?!pattern),怎么用呢,先查看下其具体的解释(JDK6.0文档):

[java] view plain copy
  1. (?=X) X, via zero-width positive lookahead
  2. (?!X) X, via zero-width negative lookahead
  3. (?<=X) X, via zero-width positive lookbehind
  4. (?<!X) X, via zero-width negative lookbehind

不太懂,不过看了下@Kevin Yang的文章使用正则表达式找出不包含特定字符串的条目后,了解前瞻(Lookahead)和后顾(Lookbehind)的概念,拷贝大牛点东西

这两个术语非常形象的描述了正则引擎的匹配行为。需要注意一点,正则表达式中的前和后和我们一般理解的前后有点不同。一段文本,我们一般习惯把文本开头的方向称作“前面”,文本末尾方向称为“后面”。但是对于正则表达式引擎来说,因为它是从文本头部向尾部开始解析的(可以通过正则选项控制解析方向),因此对于文本尾部方向,称为“前”,因为这个时候,正则引擎还没走到那块,而对文本头部方向,则称为“后”,因为正则引擎已经走过了那一块地方。如下图所示:

所谓的前瞻就是在正则表达式匹配到某个字符的时候,往“尚未解析过的文本”预先看一下,看是不是符合/不符合匹配模式,而后顾,就是在正则引擎已经匹配过的文本看看是不是符合/不符合匹配模式。符合和不符合特定匹配模式我们又称为肯定式匹配和否定式匹配。

了解了这个概念之后,上面JDK6.0文档的解释就一目了然了,哈哈,下面继续写正则表达式,不包含/>,那么表达式如下:

[java] view plain copy
  1. <input.*?hidden((?!/>).)*/>

恩恩,这次应该没问题了吧,赶紧测试:

[java] view plain copy
  1. <input type="text" id="xxx" name="xxx" value="xxx" /><input type="hidden" id="xxx" name="xxx" value="xxx" />

。。。。。。。。。还是这样,啥问题啊,淡定,再仔细想想,这个是前瞻,那么匹配到hidden时,再往前看,没有/>,接着往下走,匹配结束了,结果还是这个。。。。。

那后瞻呢?来试试,匹配到hidden时,再往后看,有/>,哈哈,赶紧的,不匹配,啥都没有了。。。。。可是事实有满足条件的input啊

再想想其他方法,先简单点的来,先不判断有无hidden,解析出这两个input,那么表达式如下:

[java] view plain copy
  1. <input.*?/>

测试下,结果如下:

[java] view plain copy
  1. <input type=\"hidden\" id=\"xxx\" name=\"xxx\" value=\"xxx\" />
  2. <input type=\"text\" id=\"xxx\" name=\"xxx\" value=\"xxx\" />

哈哈,解析了两条,那么在这个结果的基础上再通过一个正则表达式匹配下不就ok了么?,赶紧试试,第二个表达式如下:

[java] view plain copy
  1. .*hidden.*

再次解析,结果ok啦,恩恩~~,可是,问题是人家就是只要一个正则表达式搞定啊!!!!!好吧,再想想,再想想,有了:

我可以通过特殊字符串 >< 来判断下,让字符串不包含><。恩,试试,那么这个表达式如下:

[java] view plain copy
  1. <input[^(>.*?<)]*?hidden[^(>.*?<)]*?/>

这个貌似不错,先测试下,结果如下:

[java] view plain copy
  1. <input type=\"hidden\" id=\"xxx\" name=\"xxx\" value=\"xxx\" />
  2. <input type=\"text\" id=\"xxx\" name=\"xxx\" value=\"xxx\" />

哈哈,可以了啊,那再试试其他的测试用例,都可以,最后有个用例是这样子的:

[java] view plain copy
  1. "<input type='hidden' name='HTTP_REFERER' value='http://haiyuyangguang.soufun.com/bbs/5010939724~-1//515494454_515494454.htm' />  <input type='hidden' value='0' name='isfromspace' />"

测试结果如下:

[java] view plain copy
  1. <input type='hidden' value='0' name='isfromspace' />

Why?为啥这样子?淡定,分析下,没有解析出来第一个input,是因为它里面有特殊的字符吗?看看,与/、:、~、-、.有关吗?一个一个删了再测下,最后删了. 结果两条,把其他的符号还原测试下,还是两条,那就是与.有关系了,那表达式哪里出问题了?找找,哦,是那个 “.” 的问题,看看解释

[java] view plain copy
  1. .     Any character (may or may not match <u><strong>line terminators</strong></u>)
[java] view plain copy
  1. <u><strong>Line terminators</strong></u>
  2. A line terminator is a one- or two-character sequence that marks the end of a line of the input character sequence. The following are recognized as line terminators:
  3. A newline (line feed) character ('\n'),
  4. A carriage-return character followed immediately by a newline character ("\r\n"),
  5. A standalone carriage-return character ('\r'),
  6. A next-line character ('\u0085'),
  7. A line-separator character ('\u2028'), or
  8. A paragraph-separator character ('\u2029).

没有与.相关的,不过想到换个匹配,表达式如下:

[java] view plain copy
  1. <input[^(>[\\s\\S]*?<)]*?hidden[^(>[\\s\\S]*?<)]*?/>

测试下,ok!没问题了,看来[\\s\\S]比.更强大啊!

问题解决,不过不知道自己写的这个是不是遇到其他的测试用例会有问题,或者有更好的、更强大的匹配。欢迎大牛指正!

正则表达式之?、(?:pattern)、(?!pattern)、(?=pattern)理解及应用相关推荐

  1. Python正则表达式介绍 re.findall(pattern, str, flag=0)/re.I re.L re.M

    Python 正则表达式 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配. re.findall(pattern, str, flag=0) 共三个参数,patter ...

  2. Java - 正则表达式的运用(Pattern模式和Matcher匹配)

    一.绪论: 在写程序的过程中,有时会需要匹配.查找.替换或者是判断字符串的出现情况,而且有时不能用简单的纯编码方式解决这些问题,这个时候就会想到要正则表达式,无论是Java, PHH, C#,  Py ...

  3. [html] 说说你对HTML5中pattern属性的理解

    [html] 说说你对HTML5中pattern属性的理解 好像是判断input在输入时按下tab键跳转到下一个input的优先级 个人简介 我是歌谣,欢迎和大家一起交流前后端知识.放弃很容易, 但坚 ...

  4. 正则表达式、常用类(Pattern类、Matcher类、Math类、System类、Random类、BigDecimal类、Date类、SimpleDateFormat类、Calendar类)

    JAVA学习第十六天-正则表达式.常用类(Pattern类.Matcher类.Math类.System类.Random类.BigDecimal类.Date类.SimpleDateFormat类.Cal ...

  5. (?:pattern)与(?=pattern)的区别

    官方定义 (?:pattern) 匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用.这在使用 "或" 字符 (|) 来组合一个模式的各个部分 ...

  6. js中字符串正则表达式、正则法则pattern、RegExp、flags、exec

    全栈工程师开发手册 (作者:栾鹏) js系列教程3-字符串.正则表达式全解 js中字符串正则表达式 正则法则的应用 正则表达式 = /pattern/flags 其中flags中g表示匹配全部,i表示 ...

  7. python中的pattern什么意思_正则表达式中(?:pattern)、(?=pattern)、(?!pattern)、(?=pattern)和(?!pattern)...

    (?:pattern) ()表示捕获分组,()会把每个分组里的匹配的值保存起来,从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推 (?:)表示非捕获分组,和捕获分组唯一 ...

  8. Design Pattern: Observer Pattern

    1. Brief 一直对Observer Pattern和Pub/Sub Pattern有所混淆,下面打算通过这两篇Blog来梳理这两种模式.若有纰漏请大家指正. 2. Use Case 首先我们来面 ...

  9. java pattern.quote_Java Pattern quote(String)用法及代码示例

    Pattern类的quote(String)方法用于为作为参数传递给方法的指定String返回文字模式Pattern String.此方法产生一个等效于s的String,可用于创建Pattern.输入 ...

最新文章

  1. *45.程序的装入方式
  2. python爬虫表格中清除空格_爬虫清洗:python strip()函数 去空格\n\r\t函数的用法
  3. 使用 Apache Commons CLI 开发命令行工具
  4. 总是想逃避不想去面对(又是发牢骚的一天)
  5. nao机器人拆解_一些机器人硬件网站
  6. 【转】JMeter学习(十七)JMeter测试Java
  7. 关于挽救爱情的一次求学尝试
  8. ng service(服务)
  9. PTA—念数字(C语言)两种方法
  10. bpftrace 使用笔记
  11. sm4 的s盒_国密SM4算法
  12. 美通社企业新闻汇总 | 2019.1.3
  13. CSDN 博客更换皮肤
  14. ASEMI肖特基二极管MBR10200CT参数,MBR10200CT封装
  15. 在Matlab中构建最大带权生成树
  16. 我说CMMI2.0之:详细剖析(PQA)过程质量保证
  17. iframe 用法总结
  18. elementUI checkbox选中与取消选中
  19. ubuntu 自定义开机画面
  20. 一个月薪12000的北京程序员的真实生活

热门文章

  1. php 实现 html转js
  2. jQuery1.8 css模块评析
  3. 列表导航栏实例(01)
  4. 用awk数组处理两个文件的例子
  5. spring与memcache的集成
  6. gitlab 推送本地代码到远程仓库
  7. mac环境下myeclipse上配置tomcat
  8. CUDA学习(七十一)
  9. Tomcat灵活配置多项目,多端口,多域名,多虚拟目录
  10. Spring MVC 全局异常处理(1) --SimpleMappingExceptionResolver