則表達式是用于匹配字符串中字符組合的模式。在 JavaScript 中,正則表達式也是對象。這些模式被用于 RegExp 的 exec 和 test 方法, 以及 String 的 match、matchAll、replace、search 和 split 方法。正則表達式的掌握程度能粗略地看出程序員的技術底子,所以技術面試、編程競賽等 都特別喜歡考察正則表達式。本篇就帶你一起夯實一下 JavaScript 正則表達式的一些使用技巧:
在 JavaScript 的世界,創建正則表達式有2個方法: (1)使用一個正則表達式字面量,其由包含在斜杠之間的模式組成。比如 :
const reg = /ab+c/
(2)調用RegExp對象的構造函數。比如:
const reg = new RegExp("ab+c")
注意:以上2個方法雖然都能創建正則表達式,但是還是有區別的: (1)使用第一個方法,在腳本加載后正則表達式字面量就會被編譯。當正則表達式保持不變時,使用此方法可獲得更好的性能。 (2)使用第二個方法,在腳本運行過程中用構造函數創建的正則表達式會被編譯。如果正則表達式將會改變,或者它將會從用戶輸入等來源中動態地產生,就需要使用構造函數來創建正則表達式。
當然,這樣表述可能不太深刻,下面找一道面試題帶你實踐一下。
題目要求:
使用一個方法來擴展字典,該方法返回與模式匹配的單詞列表。這個模式可以包含字母(小寫)和占位符("?")。占位符只代表一個任意的字母,比如:
const fruits = new Dictionary(['banana', 'apple', 'papaya', 'cherry']);
fruits.getMatchingWords('lemon'); // must return []
fruits.getMatchingWords('cherr??'); // must return []
fruits.getMatchingWords('?a?a?a'); // must return ['banana', 'papaya']
fruits.getMatchingWords('??????'); // must return ['banana', 'papaya', 'cherry']
補充說明:
(1)單詞和模式都是小寫
(2)返回單詞的順序無關緊要
上面這道題目是典型的 正則表達式應用題,考察的知識點是2個: (1)使用 RegExp 對象 動態創建正則表達式 (2)使用 /./ 匹配一個任意字符
因此不難有如下解決方案(ps:這個是我的解決方案,雖然解法比較low,但是邏輯應該還算清晰,容易理解)
// 字典構造器
function Dictionary(words) {
this.words = words;
}
// 原型里拓展解法
Dictionary.prototype.getMatchingWords = function(pattern) {
let res = []
const reg = new RegExp("^" + pattern.replace(/\?/g, '.') + "$") // 創建正則表達式
for (let x of this.words) {
if (reg.test(x)) res.push(x)
}
return res
}
如果你有更好的解法,歡迎評論留言哈 ^_^
一個正則表達式模式是由簡單的字符所構成的,比如 /abc/;或者是簡單和特殊字符的組合,比如 /ab*c/ 或 /Chapter (\d+)\.\d*/
簡單模式是由想要匹配的具體字符組成,且嚴格匹配字符順序。比如,/abc/ 這個模式就能且僅能匹配 "abc" 字符按照順序同時出現的情況,而 "bac" 或 "cab" 等就無法匹配。
當需要匹配一個不確定的字符串時,比如尋找一個或多個 "b",或者尋找空格,可以在模式中使用特殊字符。特殊字符還包括如下:
當需要使用任何特殊字符的字面值(例如,搜索字符 *),你必須通過在它前面放一個反斜杠來轉義它。 例如,要搜索'a'后跟*后跟'b',你應該使用 /a\*b/- 反斜杠“轉義”字符 *,使其成為文字而非特殊符號。將用戶輸入轉義為正則表達式中的一個字面字符串,可以通過簡單的替換來實現:
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); //$&表示整個被匹配的字符串
}
前面講到,正則表達式可以被用于 RegExp 的 exec 和 test 方法以及 String 的 match、replace、search 和 split 方法。這些方法在 JavaScript 手冊 中有詳細的解釋,下面只簡單羅列下各自功能,不做展開:
一個簡單的快速記憶方法: (1)想要知道在一個字符串中的一個匹配是否被找到,使用 test 或 search 方法 (2)想得到更多的信息(但是比較慢)則可以使用 exec 或 match 方法
舉個栗子,使用exec方法在一個字符串中查找一個匹配:
const myRe = /d(b+)d/g;
const myArray = myRe.exec("cdbbdbsbz");
如果不需要訪問正則表達式的屬性,這個腳本通過另一個方法來創建myArray:
const myArray = /d(b+)d/g.exec("cdbbdbsbz");
// 和 "cdbbdbsbz".match(/d(b+)d/g); 相似。
// 但是 "cdbbdbsbz".match(/d(b+)d/g) 輸出數組 [ "dbbd" ],
// 而 /d(b+)d/g.exec('cdbbdbsbz') 輸出數組 [ "dbbd", "bb", index: 1, input: "cdbbdbsbz" ].
如果想通過一個字符串構建正則表達式,那么這個腳本還有另一種方法:
const myRe = new RegExp("d(b+)d", "g");
const myArray = myRe.exec("cdbbdbsbz");
一個正則表達式模式使用括號,將導致相應的子匹配被記住。例如,/a(b)c / 可以匹配字符串“abc”,并且記得“b”。回調這些括號中匹配的子串,使用數組元素[1],……[n]。
使用括號匹配的子字符串的數量是無限的。返回的數組中保存所有被發現的子匹配。下面的例子說明了如何使用括號的子字符串匹配。
下面的腳本使用 replace() 方法來轉換字符串中的單詞。在匹配到的替換文本中,腳本使用替代的, 表示第一個和第二個括號的子字符串匹配:
const re = /(\w+)\s(\w+)/;
const str = "John Smith";
const newstr = str.replace(re, "$2, $1");
console.log(newstr); // 輸出 "Smith, John"
正則表達式有六個可選參數 (flags) 允許全局和不分大小寫搜索等。這些參數既可以單獨使用也能以任意順序一起使用, 并且被包含在正則表達式實例中:
例如,re = /\w+\s/g 將創建一個查找一個或多個字符后有一個空格的正則表達式,或者組合起來像此要求的字符串:
const re = /\w+\s/g;
const str = "fee fi fo fum";
const myArray = str.match(re);
console.log(myArray);
// ["fee ", "fi ", "fo "]
使用 .exec() 方法時,與 g 標志關聯的行為是不同的。 (“class”和“argument”的作用相反:在.match()的情況下,字符串類(或數據類型)擁有該方法,而正則表達式只是一個參數,而在.exec()的情況下,它是擁有該方法的正則表達式,其中字符串是參數。對比str.match(re)與re.exec(str) ), g標志與.exec()方法一起使用獲得迭代進展:
const xArray; while(xArray = re.exec(str)) console.log(xArray);
// produces:
// ["fee ", index: 0, input: "fee fi fo fum"]
// ["fi ", index: 4, input: "fee fi fo fum"]
// ["fo ", index: 7, input: "fee fi fo fum"]
除此之外,m標志用于指定多行輸入字符串應該被視為多個行。如果使用m標志,^和$匹配的開始或結束輸入字符串中的每一行,而不是整個字符串的開始或結束。
@參考:正則表達式
.*匹配除 \n 以外的任何字符。
/[\u4E00-\u9FA5]/ 漢字
/[\uFF00-\uFFFF]/ 全角符號
/[\u0000-\u00FF]/ 半角符號
1.有四種錢的表示形式我們可以接受:"10000.00" 和 "10,000.00", 和沒有 "分" 的 "10000" 和 "10,000":^[1-9][0-9]*$
2.這表示任意一個不以0開頭的數字,但是,這也意味著一個字符"0"不通過,所以我們采用下面的形式:^(0|[1-9][0-9]*)$
3.一個0或者一個不以0開頭的數字.我們還可以允許開頭有一個負號:^(0|-?[1-9][0-9]*)$
4.這表示一個0或者一個可能為負的開頭不為0的數字.讓用戶以0開頭好了.把負號的也去掉,因為錢總不能是負的吧.下面我們要加的是說明可能的小數部分:^[0-9]+(.[0-9]+)?$
5.必須說明的是,小數點后面至少應該有1位數,所以"10."是不通過的,但是 "10" 和 "10.2" 是通過的:^[0-9]+(.[0-9]{2})?$
6.這樣我們規定小數點后面必須有兩位,如果你認為太苛刻了,可以這樣:^[0-9]+(.[0-9]{1,2})?$
7.這樣就允許用戶只寫一位小數.下面我們該考慮數字中的逗號了,我們可以這樣:^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$
8.1到3個數字,后面跟著任意個 逗號+3個數字,逗號成為可選,而不是必須:^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$
備注:這就是最終結果了,別忘了+可以用*替代如果你覺得空字符串也可以接受的話(奇怪,為什么?)最后,別忘了在用函數時去掉去掉那個反斜杠,一般的錯誤都在這里
Java中,可以使用正則表達式來提取HTML中的任意內容。以下是一個示例代碼,演示如何使用正則表達式從HTML中提取文本:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class HtmlParser { public static void main(String[] args) { String html = "<html><head><title>My Website</title></head><body><p>This is some sample text.</p></body></html>"; Pattern pattern = Pattern.compile("<p[^>]*>(.*?)</p>"); Matcher matcher = pattern.matcher(html); String pText = matcher.group(1); System.out.println(pText); } }
在上面的代碼中,我們首先定義了一個HTML字符串,然后使用Pattern和Matcher類來匹配HTML中的文本。Pattern類用于定義正則表達式,Matcher類用于在HTML中查找匹配的文本。
在正則表達式中,我們使用了<p[^>]*>來匹配以<p>開頭,后面跟著任意數量的字符,再以</p>結尾的文本。其中,[^>]*表示匹配任意數量的字符,</p>表示匹配</p>后面的任意字符。
最后,我們使用group(1)方法來獲取匹配的文本,并將其打印到控制臺上。
需要注意的是,正則表達式可以根據HTML標簽的不同來進行不同的
*請認真填寫需求信息,我們會在24小時內與您取得聯系。