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

前端之家收集整理的这篇文章主要介绍了算法(五)正则表达式-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”。

原文链接:https://www.f2er.com/regex/357884.html

猜你在找的正则表达式相关文章