Java字符串與正則表達(dá)式操作方法詳解
寫在前面
1、String在java源碼中是怎么實(shí)現(xiàn)的?
2、什么是正則表達(dá)式的DFA自動(dòng)機(jī)和NFA自動(dòng)機(jī)?
1、String
1.1、String底層實(shí)現(xiàn)
Java 6及以前版本,通過char數(shù)組,每個(gè)char占用兩個(gè)字節(jié),使得String能夠很好地處理Unicode。
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
private final char[] value;
private int offset;
private int count;
// ...其他成員和方法
}
Java 7至Java 8版本,offset和count兩個(gè)變量被移除,String.substring不再共享char[],解決內(nèi)存可能泄漏問題。
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
private final char[] value;
// ...其他成員和方法
}
Java9開始,把char[]改成了byte[] + coder(編碼標(biāo)識(shí))
1.2、str="abc"和new String(“abc”)的區(qū)別
- str=“abc”
會(huì)先檢查"abc"在不在常量池,在就不創(chuàng)建了,直接拿引用 - new String(“abc”)
先將”abc“放入常量池,再將其引用傳給new的String
1.3、使用+拼接字符串
使用+拼接字符串,代碼編譯后,會(huì)被替換成StringBuilder。并且每+的一個(gè)字符串都可能被new一個(gè)新的StringBuilder,所以建議少用+,直接用StringBuilder
1.4、如何使用String.intern節(jié)約內(nèi)存
String a = new String(“a123”).intern();
當(dāng)調(diào)用intern()時(shí),會(huì)先查看常量池中是否已有字符串”a123“, 所以當(dāng)多次用到”a123“時(shí),使用String.intern不會(huì)再創(chuàng)建新的字符串,從而節(jié)約內(nèi)存。
1.5、分割字符,split()和indexOf()用哪個(gè)
split()使用正則表達(dá)式實(shí)現(xiàn),正則表達(dá)式性能是比較不穩(wěn)定的。
indexOf()能分割時(shí)盡量用indexOf()
2、正則表達(dá)式
2.1、DFA和NFA
| 正則表達(dá)式引擎 | 構(gòu)造代價(jià) | 執(zhí)行效率 | 優(yōu)勢(shì) |
|---|---|---|---|
| NFA | 小 | 低 | 支持更多,如group、環(huán)視、占有有限量詞 |
| DFA | 大 | 高 |
NFA 自動(dòng)機(jī)回溯
str = "arrrc"
reg = "ar{1,3}c"
自動(dòng)回溯會(huì)先匹配arrr,匹配到c,發(fā)現(xiàn)不是r,就回溯到最后一個(gè)r,用reg的c去繼續(xù)匹配
2.2、怎么減少回溯?
1、貪婪模式
如上述例子就是貪婪模式
2、懶惰模式
str = "arrrc"
reg = "ar{1,3}?c"
懶惰模式會(huì)先匹配ar,發(fā)現(xiàn)已經(jīng)有一個(gè)r了,就開始用c接著匹配
3、獨(dú)占模式
str = "arrc"
reg = "ar{1,3}+rc"
獨(dú)占模式會(huì)先匹配ar,發(fā)現(xiàn)已經(jīng)有一個(gè)r了,就開始用rc接著匹配,不會(huì)回溯
下面這種獨(dú)占模式會(huì)回溯
str = "arrc"
reg = "ar{1,3}+c"
獨(dú)占模式會(huì)先匹配ar,發(fā)現(xiàn)已經(jīng)有一個(gè)r了,就開始用c接著匹配,匹配失敗回溯
總結(jié):
1、少用貪婪模式,多用獨(dú)占模式
2、減少分支選擇,如將”(abcd|abef)“替換為”ab(cd|ef)“
3、減少捕獲嵌套。
捕獲組: 一個(gè) ()里面的就是一個(gè)不獲取
非捕獲組:一個(gè)(?:EXP)就是一個(gè)非捕獲組
str = "<input id=1>文本</input>" reg = "(<input.*?)(.*?)(</input)" # 上面reg包含了3個(gè)捕獲組,所以如果輸出捕獲結(jié)果會(huì)有整個(gè)匹配到的內(nèi)容+括號(hào)里面的,4組字符串 str = "<input id=1>文本</input>" reg = "(?:<input.*?)(.*?)(?:</input)" # 上面reg包含了1個(gè)捕獲組,所以如果輸出捕獲結(jié)果會(huì)有整個(gè)匹配到的內(nèi)容+捕獲組括號(hào)里面的,2組字符串
到此這篇關(guān)于Java字符串與正則表達(dá)式操作的文章就介紹到這了,更多相關(guān)Java字符串與正則表達(dá)式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
簡(jiǎn)單實(shí)現(xiàn)java數(shù)獨(dú)游戲
這篇文章主要教大家如何簡(jiǎn)單實(shí)現(xiàn)java數(shù)獨(dú)游戲,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12
關(guān)于JAVA8的 Stream學(xué)習(xí)
這篇文章主要介紹了JAVA8 Stream學(xué)習(xí)方法的相關(guān)資料,需要的朋友可以參考下面文章內(nèi)容2021-09-09
AntDesign多環(huán)境配置啟動(dòng)過程詳解
這篇文章主要為大家介紹了AntDesign多環(huán)境配置啟動(dòng)過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
Java實(shí)現(xiàn)四則混合運(yùn)算代碼示例
這篇文章主要介紹了Java實(shí)現(xiàn)四則混合運(yùn)算代碼示例,文中展示了詳細(xì)代碼,具有一定參考價(jià)值,需要的朋友可以了解下。2017-10-10
springboot集成PageHelper分頁(yè)失效的原因及解決
項(xiàng)目啟動(dòng)初期,在集成mybatis的分頁(yè)插件,自定義封裝了一個(gè)分頁(yè)的工具類,方便后期項(xiàng)目的擴(kuò)展,結(jié)果無法分頁(yè)了,怎么設(shè)置搞都沒辦法正常分頁(yè),所以本文將給大家介紹一下springboot集成PageHelper分頁(yè)失效的原因及解決,需要的朋友可以參考下2023-10-10
mybatis-plus中l(wèi)ambdaQuery()與lambdaUpdate()比較常見的使用方法總結(jié)
mybatis-plus是在mybatis的基礎(chǔ)上做增強(qiáng)不做改變,簡(jiǎn)化了CRUD操作,下面這篇文章主要給大家介紹了關(guān)于mybatis-plus中l(wèi)ambdaQuery()與lambdaUpdate()比較常見的使用方法,需要的朋友可以參考下2022-09-09
java語言自行實(shí)現(xiàn)ULID過程底層原理詳解
這篇文章主要為大家介紹了java語言自行實(shí)現(xiàn)ULID過程底層原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
java中對(duì)list分頁(yè)并顯示數(shù)據(jù)到頁(yè)面實(shí)例代碼
這篇文章主要介紹了java中對(duì)list分頁(yè)并顯示數(shù)據(jù)到頁(yè)面實(shí)例代碼,分享了相關(guān)代碼示例,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-02-02

