`

算法(五)正则表达式-Regex

 
阅读更多

 

js六种正则表达式方法:matchs,test

        正则表达式方法:reg.test(str),exec()

        String对象方法:str.match(reg),search(),replace(),split()

 

js最常用test

        /\s+\w+\s+/.test("  llyu ");对

        "/\s+\w+\s+/".test("  llyu ")错

 

js正则语法

        g (全文查找) 

        i (忽略大小写) 

        m (多行查找) 

        用法/a/gi;

        "/"为开始和结束标志

js正则用例

        String.prototype.trim=function(){

                return this.replace(/(^\s+)|(\s+$)/g,"");

        }

 

 

java两种正则表达式方法:pattern,String

        Pattern类

                 Pattern p = Pattern.compile("(?<!c)a(\\d+)bd"); 

                 Matcher m = p.matcher("da12bca3434bdca4343bdca234bm"); 

                 while(m.find()){ 

                   System.out.println(m.group(1)); //我们只要捕获组1的数字即可。结果 3434 

                   System.out.println(m.group(0)); // 0组是整个表达式,看这里,并没有提炼出(?<!c)的字符 。结果 a3434bd 

                 } 

 

 

分组,使用小括号"()"来指定

分组可以分为两种形式,捕获组和非捕获组。

 

捕获组 可以用“Back引用”

        引用前面的表达式所捕获到的文本序列(是文本不是正则表达式)

        \1(组1)就是对引号这个分组的引用,

 

非捕获组:为了节省内存等开销;以(?)开头

        5中常见非捕获组

        (?:X) X,作为非捕获组 

        (?=X ) 零宽度正先行断言。仅当子表达式 X 在 此位置的右侧匹配时才继续匹配。例如,\w+(?=\d) 与后跟数字的单词匹配,而不与该数字匹配。此构造不会回溯。 

        (?!X) 零宽度负先行断言。仅当子表达式 X 不在 此位置的右侧匹配时才继续匹配。例如,例如,\w+(?!\d) 与后不跟数字的单词匹配,而不与该数字匹配。 

        (?<=X) 零宽度正后发断言。仅当子表达式 X 在 此位置的左侧匹配时才继续匹配。例如,(?<=19)99 与跟在 19 后面的 99 的实例匹配。此构造不会回溯。 

        (?<!X) 零宽度负后发断言。仅当子表达式 X 不在此位置的左侧匹配时才继续匹配。例如,(?<!19)99 与不跟在 19 后面的 99 的实例匹配 

 

 

 

ab33cd55cd66cd

ab(.*)cd        \1得到33cd55cd66

ab(.*?)cd        \1得到33

 

 

//匹配不包含"party"-----"((?!party).)*"

Ju(ne|ly)不必写成ju((ne)|(jly))

 

 

Pattern p = Pattern.compile(".*?(?<!c)a(\\d+)bd.*?");

Matcher m = p.matcher("dxa34bdza43bdca23bm"); 

while(m.find()){ 

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

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

}

结果:

0-->7

34

7-->13

43

 

Pattern p = Pattern.compile("^.*?(?<!c)a(\\d+)bd.*?$");

结果:

0-->19

34

 

Pattern p = Pattern.compile(".*?(?<!c)a(\\d+)bd.*?$");

0-->19

34

 

Pattern p = Pattern.compile("^.*?(?<!c)a(\\d+)bd.*?");

结果:

0-->7

34

 

Pattern p = Pattern.compile(".*(?<!c)a(\\d+)bd.*");

结果:

0-->19

43

 

 

 

贪婪匹配

        a.*b 将匹配满足条件最长的字符串 a=====b=====b 

        工作方式: 

        首先将:a=====b=====b=== 全部吃掉,从右边一个一个地吐出来 

        1. a=====b=====b=== 不匹配,吐出一字符 

        2. a=====b=====b== 不匹配,再吐出一字符 

        3. a=====b=====b= 不匹配,再吐出一字符 

        4. a=====b=====b 匹配了,结束。

懒惰匹配

        a.*? 将匹配满足条件最短的字符串 a=====b 

        工作方式: 

        1. a 不能匹配表达式,继续吃 

        2. a= 不能匹配表达式,继续吃 

        3. a== 不能匹配表达式,继续吃 

        4. a=== 不能匹配表达式,继续吃 

        5. a==== 不能匹配表达式,继续吃 

        6. a===== 不能匹配表达式,继续吃 

        7. a=====b 呵呵,终于能匹配表达式了,匹配结束。 

 

 

 

如果学过编译原理的话应该知道 NFA, 

Java 中正则表达式引擎采用的就是 NFA。反正我是没学过编译原理,也不懂“非确定型有穷自动机”

 

按匹配拆分下 

dxa34bdz a  43    bd  ca23bm 

.*      a  \\d+  bd  .* 

整个串就完全符合匹配所以根本不需要去掉末尾字符了 

 

 

 

 

 

 

 

//                Pattern p = Pattern.compile("Brand=[0-9]{1,3}(&page=[0-9]+)?$");

                Pattern p = Pattern.compile("Brand=[0-9]{1,3}(&page=[0-9]+)?");

                Matcher m = p.matcher("Brand=31&page=1a2"); 

                while(m.find()){ 

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

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

                }

 

                String reg="Brand=[0-9]{1,3}(&page=[0-9]+)?";

                String str="Brand=31&page=1a2"; 

                System.out.println(str.matches(reg));

 

结果:

0-->15

&page=1

false

 

str.matcher(reg)检查str完全符合reg,故此时"^","$"对reg可有可无 

p.matcher(str)检查str是否包含符合reg的子串,故此时"^","$"对reg是有作用的

 

脚本放在 <body>的最后比较好,不会阻塞浏览器的下载线程, 

可以比较一下效果,会快很多,尤其是在带图片的页面中。  

 

(?idmsux-idmsux:X)  X,作为带有给定标志 on - off 的非捕获组 

(?=X) X,通过零宽度的正 lookahead 

(?!X) X,通过零宽度的负 lookahead 

(? <=X) X,通过零宽度的正 lookbehind 

 

"abc(?i)def(?-i)g"

 

就表示abcg为小写 deg可大写的模式 

 

捕获组,可以被记录下来放于内存中以便反向引用

非捕获组,可以提高匹配效率,节省内存 

 

(?i) 也可以启用不区分大小写的匹配。 

那"abc(?i)def(?-i)g" 

 

Ju(?:ne|ly)

(?i) 打开忽略大小写开关,(?-i) 关掉忽略大小写开关,或者也可以 

写成:abc(?i:def)g

 

 

Pattern p = Pattern.compile("(? <= <(\\w+)>)"); 

Matcher m = p.matcher(textStr); 

 

怎么提示我(? <= <(\\w+)>) 

红色的部分出错 

 

Exception in thread "main" java.util.regex.PatternSyntaxException: Look-behind group does not have an obvious maximum length near index 10 

(? <= <(\w+)>)

lookbehind 其中所指定的字符必须是指定数量的,不能用 * + 之类的,但可以用 {0, 100} 这种确定型的。 

 

lookahead 没有这种限制。 

 

 

\1 这个是反向引用,只是记住 9 个捕获组 \10 表示组 1 和字符 0。

 

 

                 String str = "<b>aaaa</b>\n" +

         "<h1>bbbbb</h1>\n" +

         "<book>adfasdfadfasa\nsdfasdfadfasdf</book>\n" +

         "<b>aaaa</b>";

 

//                 Pattern pattern = Pattern.compile("(?<=<(.{1,100}?)>)(?s:.)*?(?=</\\1>)");

                 Pattern pattern = Pattern.compile("(?<=<(.{1,100}?)>)(?s:.)*?(?=</\\1>)");

                 Matcher matcher = pattern.matcher(str);

                 while(matcher.find()) {

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

                     System.out.println();

                 }

 

 

(? <= <(\\w{0,100})>).*(?= </\\1) 

和 

(? <= <(.{1,100}?)>)(?s:.)*?(?= </\\1>) 

这个有哪些区别啊? 

就加了一个Pattern.DOTALL? 

在 dotall 模式中,表达式 . 可以匹配任何字符,包括行结束符。默认情况下,此表达式不匹配行结束符。 

 

为什么你这个会匹配对称的啊? 我看不出里面的奥妙,能不能再解释一下啊? 

 

对了为什么{1,100}后面加一个?号呢,我去了好象不行 

还有(?s:.)*?也加了一个?号呢)? 

我知道加?是代表勉强是吧,能不能通俗一点给我讲一下啊? 

去了,为什么不行呢?奇怪 

谢谢先

 

(?s:.) 将这个点用于 DOTALL 模式下,因为 <book>... </book> 中我加了个“\n”。 

 
分享到:
评论

相关推荐

    正则表达式(regex)C语言源码,超强查找/替换算法

    正则表达式(Regular Expression,简称regex)是编程领域中一种强大的文本处理工具,它用于在字符串中查找、替换或匹配特定模式。在C语言中,实现正则表达式功能通常需要借助第三方库,比如本案例中提到的Henry ...

    正则表达式 到 nfa dfa

    正则表达式,简称regex,是由字符、元字符和运算符组成的模式,用于描述一系列字符串的共同特征。常见的元字符包括`.`, `*`, `+`, `?`, `{}`, `|`, `()`, `\`等。例如,`a*b`表示零个或多个'a'后跟一个'b'。`.`代表...

    Java使用正则表达式提取XML节点内容的方法示例

    为了帮助开发者更好地掌握Java正则表达式技术,我们提供了一系列的Java正则表达式技巧大全,包括《Java正则表达式技巧大全》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧...

    正则表达式转换为NFA(Regex to NFA).jar

    用JAVA写的一个将正则表达式转换为NFA的代码,基于Thompson算法的思想,递归构建NFA。jar为源码文件。 输出非确定有限自动状态机的有向图。如正则表达式: c(a|b)NFA为:0-c-&gt;1-ep-&gt;2-a-&gt;3-ep-&gt;7 ,0-c-&gt;1-ep-&gt;4-b-&gt;5-...

    正则表达式转NFA实现

    正则表达式通常简称为“regex”或“regexp”,可以表示一系列简单的到复杂的字符模式。 正则表达式的转换通常涉及到将其转化为一种计算模型,以便更方便地进行匹配操作。其中,非确定性有限自动机(NFA,Non-...

    通过正则表达式生成数据

    正则表达式(Regular Expression,简称regex)是一种强大的文本处理工具,它用于匹配、查找、替换等操作,涉及字符串的模式匹配。在本主题中,我们将深入探讨如何使用正则表达式来生成满足特定条件的随机数据。这在...

    GNU regex 正则表达式 修正版

    6. `regex.c`是实现了正则表达式功能的核心源代码文件,修正版的改动可能涉及其中的关键算法和数据结构,以提高性能和减少问题。 7. `说明.txt`文件可能包含了关于修正版的详细说明,包括如何编译、如何使用以及...

    深入浅出之正则表达式

    正则表达式(Regular Expression,简称regex)是一串由字符和特殊符号组成的字符串,用来定义一个搜索模式。这个模式可以用来检查、替换、分割或提取文本中的特定部分。例如,`\d{3}-\d{4}` 可以匹配像 "123-4567" ...

    正则表达式匹配算法小结

    正则表达式(Regular Expression, 简称 Regex 或 RE)是一种用于描述字符序列的模式语言,被广泛应用于文本处理、数据验证以及搜索等场景。正则表达式的匹配算法是实现这些功能的基础,其性能直接影响到应用的效率。...

    js-sandbox-14:正则表达式-评估函数

    正则表达式,正则表达式或正则表达式(有时称为有理表达式)是定义搜索模式的一系列字符。 通常,字符串搜索算法会将此类模式用于字符串的“查找”或“查找并替换”操作,或用于输入验证。 正则表达式是用于匹配...

    正则表达式测试工具 regex

    正则表达式(Regular Expression,简称regex)是一种强大的文本处理工具,用于匹配、查找、替换等操作。在编程和数据分析领域,正则表达式扮演着不可或缺的角色。标题提到的"正则表达式测试工具 regex"是一款专为...

    Python中使用 Thompson算法的 正则表达式引擎

    例如,`regex`库(对应压缩包中的`regex-master`)就是这样一个库,它提供了Thompson算法的实现,以优化正则表达式的性能。`regex`库除了支持标准的`re`模块特性外,还增加了更多的高级功能,比如命名捕获组、无限...

    delphi正则表达式解析器

    Delphi正则表达式解析器的源码可以帮助开发者学习正则表达式的实现细节,例如如何编译正则表达式模式,如何执行匹配算法,以及如何处理复杂的正则表达式构造。通过研究和学习源码,开发者可以更好地理解和优化他们的...

    《精通正则表达式第三版 E文》

    这本书详尽地介绍了正则表达式的语法、使用技巧以及背后的匹配算法,是许多开发者学习和提升正则表达式技能的重要参考资料。在IT行业中,正则表达式是一种强大的文本处理工具,广泛应用于数据验证、搜索、替换等场景...

    正则表达式自动生成器(regex builder)2.0.7z

    正则表达式(Regex)是一种强大的文本处理工具,用于匹配、查找、替换符合特定模式的字符串。在编程中,正则表达式常被用来验证输入数据的格式,提取信息,或者进行复杂的文本操作。"正则表达式自动生成器"是一款...

    Regex-UAbALL:常规语言构成了具有较少表示能力的语言类别,并且有可能开发具有多种应用程序的识别算法,例如词法分析,动画系统,超文本和超媒体(Menezes,2000年)。 可以通过有限的自动机和正则表达式(REGEX)来表示正则语言。 REGEX-正则表达式-通过一种字符串模式来指定一种常规语言的一种顺序方式,该模式解释了可以由有限自动机描述的相同内容。 例如,在UNIX表示法中,REGEX“ [AZ] [az] * [] [AZ] [AZ]””表示一个单词,该单词以大写字母开头,后跟一个空格和

    REGEX-正则表达式-通过一种字符串模式来指定一种常规语言的一种顺序方式,该模式解释了可以由有限自动机描述的相同内容。 例如,在UNIX的REGEX表示法中,“ [AZ] [az] * [] [AZ] [AZ]”表示一个单词,该单词以大写...

    强大的JAVA正则表达式处理包jakarta-oro

    1. **高效性能**:Jakarta ORO采用了优化的算法和数据结构,对于大型文本和复杂的正则表达式模式匹配,它的性能通常优于Java内置的正则表达式实现。 2. **预编译模式**:与Java内置的正则表达式不同,ORO支持预编译...

    C语言实现正则表达式检测

    例如,可能会有一个`validate_regex()`函数,用于执行匹配操作,以及一个`compile_regex()`函数,用于编译正则表达式。 在实际应用中,我们可能需要考虑以下几个方面: - **错误处理**:编译正则表达式时,可能会...

    正则表达式C语言源码

    在计算机科学和编程领域,正则表达式(Regular Expression,简称regex)被广泛应用于数据验证、搜索与替换等任务。C语言,作为一门基础且通用的编程语言,虽然没有内置的正则表达式库,但可以通过第三方库来实现正则...

    正则表达式系统教程.CHM

    - **调试工具**:如regex101、RegExr等在线工具,可实时测试和调试正则表达式。 - **性能优化**:避免过度复杂的正则表达式,考虑使用更高效的匹配方法。 通过学习“正则表达式系统教程”,你可以深入了解正则...

Global site tag (gtag.js) - Google Analytics