代碼中使用正則表達式

1 基礎

1.1 學習的意義

正則表達式脫離語言,和數據結構與算法同樣,做爲程序員的軟技能。目前存在的問題:不受重視 優勢:javascript

  • 顯著的提高代碼質量
  • 靈活多變
  • 強大的數據校驗支持

1.2 構建

構建正則表達式的方式不少,有如下的構造方法。java

var regex1 = /itagn/g;
var regex2 = new RegExp('itagn', 'g');
var regex3 = new RegExp(/itagn/, 'g');
var regex4 = new RegExp(/itagn/g);
複製代碼

1.3 修飾符

經常使用的修飾符:程序員

g: 全局匹配模式。做用於全部字符串,發現第一個匹配項後不會當即中止
i: 不區分大小寫模式。忽略大小寫進行匹配
m: 多行匹配模式。支持換行文本匹配
複製代碼

新增的修飾符:web

u: Unicode模式。用來處理Unicode大於	\uFFFF的單個字符(超過\uFFFF會被程序員解析爲兩個字符)
y: 粘連模式。和g同樣做爲全局匹配,區別是g的下一次匹配不要求位置,可是y下一次匹配要求緊跟這此次匹配項以後
s: dotAll模式。正則表達式中點(.)做爲匹配(除換行符\n,回車符\r,行分隔符,段分隔符)任意單個字符,支持點(.)真正匹配全部單個字符
複製代碼

2 匹配規則

2.1 關鍵詞匹配

經常使用的匹配方式,一般是經過匹配關鍵詞來實現定位正則表達式

示例1:正則設定手機號格式算法

var regex = /^(086-)?1[345789]\d{9}$/;
regex.test('15512341234'); // true
複製代碼

示例2:正則將時間格式轉換:年/月/日(yyyy/mm/dd)數據結構

var date = new Date();
var time = date.toISOString();
var regex = /^(\d{4})-(\d{2})-(\d{2})(.+)$/;
time.replace(regex, '$1/$2/$3'); // "2019/08/23"
複製代碼

2.2 位置匹配

經常使用的位置匹配就是^(匹配字符串開頭)和$(匹配字符串結尾)。
另外還有\b(匹配一個單詞邊界),\B(匹配非單詞邊界)學習

示例1:把字符串中全部單詞的首字母大寫ui

var regex = /\b[a-z]/g;
var str = 'i am itagn who is a web developers';
str.replace(regex, word => word.toUpperCase()); // "I Am Itagn Who Is A Web Developers"
複製代碼

示例2:把字符串中全部每超過3個字符的單詞就增長一個短橫(-)spa

var regex = /[a-zA-Z]{3}\B/g;
var str = 'i am itagn who is a web developers';
str.replace(regex, word => word + '-'); // "i am ita-gn who is a web dev-elo-per-s"
複製代碼

3 高級用法

3.1 貪婪匹配

貪婪匹配:趨向於最大長度匹配。(默認)
非貪婪匹配:匹配到結果就好。
複製代碼

示例1:貪婪匹配獲取數字

'123456789'.match(/\d+/)[0]; // "123456789"
複製代碼

示例2:非貪婪匹配獲取數字

'123456789'.match(/\d+?/)[0]; // "1"
複製代碼

3.2 懶惰匹配

上文中的非貪婪匹配就用到了惰性匹配,其特色就是在其餘重複量詞後面加上限定符(?) 惰性匹配的特色:

  • 重複量詞後面添加限定符(?)
  • 惰性匹配會盡量少的匹配字符,同時必須知足整個匹配模式。

示例1:非惰性匹配惰性匹配

'123412341234'.match(/1(\d+)4/)[0]; // "123412341234"
'123412341234'.match(/1(\d+?)4/)[0]; // "1234"
複製代碼

3.3 先行斷言/先行否認斷言

先行斷言:x只有在y前面才匹配,必須寫成/x(?=y)/的形式。
先行否認斷言:x只有不在y前面才匹配,必須寫成/x(?!y)/的形式。
複製代碼

匹配的結果是x,如經過match方法匹配項會返回x。

示例1:先行斷言先行否認斷言的用法

/itagn(?=2019)/.test('itagn2019'); // true
/itagn(?=2019)/.test('itagn-2019'); // false

/itagn(?!2019)/.test('itagn2019'); // false
/itagn(?!2019)/.test('itagn-2019'); // true
複製代碼

咱們能夠發現,這裏同時包含了關鍵詞匹配位置匹配,屬於正則的高級匹配。 接下來咱們能夠看看怎麼處理業務中的問題。 示例2:經過正則把數字 1234567890 轉換成美圓 $1,234,567,890

var str = '1234567890';
var regex = /(?!^)(?=(\d{3})+$)/g;
str.replace(regex, ',').replace(/^/, '$'); // "$1,234,567,890"
複製代碼

3.4 後行斷言/後行否認斷言

後行斷言和先行斷言正好相反。

後行斷言:x只有在y後面才匹配,必須寫成/(?<=y)x/的形式。
後行否認斷言:x只有再也不y後面才匹配,必須寫成/(?<!y)x/的形式。
複製代碼

匹配的結果是x,如經過match方法匹配項會返回x。

示例1:後行斷言後行否認斷言的用法

/(?<=2019)itagn/.test('2019itagn'); // true /(?<=2019)itagn/.test('2019-itagn'); // false /(?<!2019)itagn/.test('2019itagn'); // false /(?<!2019)itagn/.test('2019-itagn'); // true 複製代碼

示例2:經過正則把美圓 $123,456,789,000 變成美圓 $1234,5678,9000 試着經過先行斷言+先行否認斷言來處理

var str = '$123,456,789,000';
var regex = /(?!^)(?=(\d{4})+$)/g;
str.replace(/,/g, '').replace(regex, ','); // "$,1234,5678,9000"
複製代碼

因爲第一個字符是而不是數字,在這裏`先行否認斷言`判斷字符串初始無效,因此在和數字中間出現了逗號分隔符。
同時也不能把(?!^)改爲(?!$),由於匹配到1234,56789,000的時候前面的字符也不是$而是1,因此仍然會在開頭添加一個逗號(,)。

var str = '$123,456,789,000';
var regex = /(?!\$)(?=(\d{4})+$)/g;
str.replace(/,/g, '').replace(regex, ','); // "$,1234,5678,9000"
複製代碼

咱們發現,咱們只須要排除一種狀況,就是後面跟着逗號的狀況。    
這個時候知足後行斷言匹配項(x)在美圓符號後面。
試着經過後行否認斷言代替先行否認斷言

var str = '$123,456,789,000';
var regex = /(?<!\$)(?=(\d{4})+$)/g;
str.replace(/,/g, '').replace(regex, ','); // "$1234,5678,9000"
複製代碼
相關文章
相關標籤/搜索