javascript 正则表达式 转换 java 正则表达式_正则表达式java,javaScript应用

dfa nfa 混合;捕获;断言;

正则引擎大体上可分为不同的两类:DFA和NFA,而NFA又基本上可以分为传统型NFA和POSIX NFA。

1.正则语法

捕获组:

没用()的字符都是一个一个捕获的从左往右,要么就是一个字符一个字符匹配

(pattern):捕获该匹配的子表达式;可用$1,$2,$3获得

(?:pattern):匹配但不捕获正则表达式,,即用$1,$2不能获得

例如:((A)(B(C))):有四个组:(C);(B(C));(A);((A)(B(C)))

js中:$1能获得分组值;java中matcher的group(0)能获得分组

断言:(我猜匹配对象前面是什么;后面是不能是什么;前面是什么;前面不能是什么)

1.断言后面是什么(?=pattern):Windows (?=95|98|NT|2000)断言Windows后面的是95或者98或者2000

2.断言后面不是什么(?!pattern): Windows (?=95|98|NT|2000)断言Windows后面的不是95或者98或者2000

3.断言前面是什么(?<=pattern): (?<=95|98|NT|2000)Windows断言Windows前面的是95或者98或者2000

4.断言前面不是什么(?

表达式:

[abc]:方括号间的任意字符;[^abc]:任何不在方括号间的文字

[0-9]:0到9间的数字;[a-z][A-Z][A-z][adgk][]

(x|y):查找任何匹配项

---------------------------------------

元字符:

\d;\s:空白字符;\b:匹配单子边界;\uxxxx:查找以16进制数xxxx规定的Unicode字符

.;w:单词字符;W:非单词字符;\d ;\D;\s;\S;\b:匹配一个单词边界即与单词与空格的位置("er\b"匹配"never"中的"er",但不匹配"verb"中的"er")

;\B("er\B"匹配"verb"中的"er",但不匹配"never"中的"er");\0:null字符;\n换行符;\f:换页;\r:回车符;\t:制表符;

\v:垂直制表符;\xxx:以八进制规定的字符;\xdd:十六进制的字符;

量词:

n+:1到多;n*:0到多;n?:0到1

{X} ;{X,};{X,Y};

^n:以开头;n$:以结尾;

?=n:其后紧跟字符串n的字符串;?!n:没有紧接字符串n的字符串

修饰符:

i;g:执行全局匹配;m:多行匹配

2.javaScript中的应用

语法:/正则表达式主体/修饰符(可选)

1)RegExp对象:预定义了属性和方法的表达式对象

语法:var patt=new RegExp(pattern,modifiers);var patt=/pattern/modifiers;

var re = new RegExp("\\w+");var re = /\w+/;

/w/就是一个RegExp对象

test():只是测试是否能匹配上

exec():匹配到的结果存在数组中,需要注意的是:匹配到数组的原则:先整体匹配结果-》RegExp.$1->RegExp.$2

compile():编译正则表达式没什么用

例子:

var patt1=new RegExp("The\\sbest");var patt2=new RegExp("(The)\\s(best)");var aa=patt1.exec("The best things in life are free");

console.log(aa);

2)字符串方法:

search:获得查找匹配字符串起始位置放回int:var str="Mr. Blue has a blue house";str.search(/blue/i)//结果4

match:找到一个或多个正则表达式的结果;返回Arrary;也能获得分组$1,$2的值例如:$1 = RegExp.$1

replace:str.replace(/blue/g,"red");替换后返回新的字符串

split:string.split(separator,limit):按匹配的结果分隔;返回数组

3.java中的应用:java.util.regex提供了下面三个类

Pattern ;Matcher ;PatternSyntaxException

Pattern.matches(pattern,content):可以判断content中是否有pattern匹配,不需要Pattern实例

一般我们用java正则需要创建Matcher对象:Pattern p = Pattern.compile(pattern)->Matcher m = p.matcher(content)->之后在对matcher对象做处理

索引方法:start() ;start(int group);end();end(int group)

研究方法:lookingAt() ;find() ;find(int start);matches()

替换方法:appendReplacement(StringBuffer sb, String replacement);appendTail(StringBuffer sb);replaceAll(String replacement) ;replaceFirst(String replacement);quoteReplacement(String s)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

//直接使用Pattern

public static voidregexTest1(){

String content= "I am noob from runoob.com.";

String pattern= ".*runoob.*";

boolean isMatch= Pattern.matches(pattern, content);//是否匹配不需要实例

Pattern p = Pattern.compile(pattern); //创建实例对象

Matcher m = p.matcher(content); //创建Matcher对象

while(m.find()){

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

}

System.out.println("1.matches:字符串中是否包含了 'runoob' 子字符串?" +isMatch);

}//Matcher 类的方法//1.索引方法:start;end;

public static voidregexTest2(){

String REGEX= "\\bcat\\b";

String INPUT= "cat cat cat cattie cat";int count = 0;//获得matcher对象

Pattern p =Pattern.compile(REGEX);

Matcher m=p.matcher(INPUT);while(m.find()){

count++;

System.out.println("Match number"+count);

System.out.println("start():"+m.start());//返回以前匹配的初始索引必须之前要有匹配

System.out.println("end():"+m.end());//返回以前匹配的结束索引必须之前要有匹配

}

}//2.研究方法:matches 与lookingAt 方法区别:matches尝试整个区间匹配;lookingAt只匹配开头部分

public static voidregexTest3(){

String REGEX= "foo";

String INPUT= "fooooooooooooooooo";

String INPUT2= "ooooofoooooooooooo";

Pattern pattern=Pattern.compile(REGEX);

Matcher matcher=pattern.matcher(INPUT);

Matcher matcher2=pattern.matcher(INPUT2);//测试

System.out.println("Current REGEX is:"+REGEX);

System.out.println("Current INPUT is:"+INPUT);

System.out.println("Current INPUT2 is:"+INPUT2);

System.out.println("lookingAt():"+matcher.lookingAt());

System.out.println("matches():"+matcher.matches());

System.out.println("lookingAt():"+matcher2.lookingAt());

}//3.替换方法:replace;replaceAll:不同在与:replaceFirst匹配第一个;replaceAll匹配所以

public static voidregexTest4(){

String REGEX= "dog";

String INPUT= "The dog says meow.All dogs say meow.";

String REPLACE= "cat";

Pattern p=Pattern.compile(REGEX);

Matcher m=p.matcher(INPUT);

System.out.println(m.replaceFirst(REPLACE));//只匹配第一个

System.out.println(m.replaceAll(REPLACE));//全部匹配

}//4.appendReplacement 和 appendTail:用于文本替换

public static voidregexTest5(){

String REGEX= "a*b";

String INPUT= "aabfooaabfooabfoob";

String REPLACE= "-";

Pattern p=Pattern.compile(REGEX);

Matcher m=p.matcher(INPUT);

StringBuffer sb= newStringBuffer();while(m.find()){

m.appendReplacement(sb, REPLACE);

}

m.appendTail(sb);

System.out.println(sb);

}

View Code

4.NFA/DFA算法:将正则表达式转为机器语言加识别速度

ε边存在的最大的理由:使用ε边来给出一个简洁的算法把一个正则表达式转换成ε-NFA。

状态机分类:确定的有穷状态自动机(DFA);非确定的有穷状态自动机(NFA);带有ε边的非确定的状态机(ε-NFA)

1)从正则表达式到ε-NFA

正则表达式有规则的串联、并联、重复、可选等操作;对应的ε-NFA也需要规定出对应的规则

1.字符集:直接按步骤走即可

16e6998b23d865b69f6185513cb42213.png

2.串联:一个状态图结束走后直接下一个状态图

2d08e8c0946ca5c8267922a7fd646a11.png

3.并联:每个状态图,开始结束都用一个start,end连接(ε)

5fdb30f93c8135592d8b62baed452760.png

4.重复:当状态走到结束状态的时候,如果遇到一个可以让规则接受的字符串,则再次回到结束状态

6a334f7e3d57dfc3f3057d0fca2c349e.png

5.可选:规则的状态图的起始状态和结束状态连接起来

7dc11198b7b3d12a8ad82174802d03a0.png

如果重复使用的是0次以上重复,也就是原来的重复加上可选的结果,那么可以简单地把图4.4的Start状态去掉,让End状态同时拥有起始状态和结束状态两个角色,[Start]和[End]则保持原状。

作用:将5种构造状态图的办法都对应到了5种构造规则的办法上了。对于 任意的一个正则表达式,我们仅需要把这个表达式还原成那5种构造的嵌套,然后把每一步构造都对应到一个状态图的构造上,就可以将一个正则表达式转换成一个 ε-NFA了

6.用法例子:

正则表达式:((aa|bb)|((ab|ba)(aa|bb)*(ab|ba)))*

状态机:

3574f0b23944d2ec468be48b2b0099bc.png

7.消除非确定性:只得到ε-NFA还是不行的,因为ε-NFA的不确定性太大了,直接根据ε-NFA跑的话,每一次都会得到大量的临时状态集合,会极大地降低效率

1)消除ε边算法

2)

-------------------------太多了还不怎么能用到不看了NFA/DFA链接大家自己看看把

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaScript正则表达式Java正则表达式在语法上有一些差异,但是它们的基本概念和用法是相似的。下面是将JavaScript正则表达式转换Java正则表达式的一些常见规则: 1. 语法差异: - JavaScript正则表达式使用斜杠(/)作为定界符,而Java正则表达式使用双引号(")作为定界符。 - JavaScript正则表达式中的特殊字符需要进行义,而Java正则表达式中的特殊字符不需要义。 2. 字符类: - JavaScript正则表达式中的字符类使用方括号([])表示,而Java正则表达式中使用方括号([])或者Unicode义(\p{...})表示。 - JavaScript正则表达式中的字符类可以使用连字符(-)表示范围,而Java正则表达式中需要使用Unicode义(\uXXXX)表示范围。 3. 量词: - JavaScript正则表达式中的量词使用花括号({})表示,而Java正则表达式中使用花括号({})或者问号(?)表示。 - JavaScript正则表达式中的贪婪量词默认是贪婪模式,而Java正则表达式中的贪婪量词需要在后面添加问号(?)来表示非贪婪模式。 4. 边界匹配: - JavaScript正则表达式中的边界匹配使用插入符号(^)和美元符号($)表示,而Java正则表达式中使用\A和\Z表示。 5. 其他差异: - JavaScript正则表达式中的捕获组使用圆括号(())表示,而Java正则表达式中使用圆括号(())或者方括号([])表示。 - JavaScript正则表达式中的反向引用使用反斜杠加数字(\1、\2等)表示,而Java正则表达式中使用美元符号加数字($1、$2等)表示。 以上是一些常见的JavaScript正则表达式转换Java正则表达式的规则。具体转换时,还需要根据具体的正则表达式进行适当的调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值