晴明的博客园 GitHub      CodePen      CodeWars     

[regex] 正则 积累

名称 作用
? {0,1}
* {0,}
+ {1,}
. 匹配任意单个字符,但是行结束符除外:\n \r \u2028\u2029。如果要匹配包括 \n 在内的任意字符,可以使用[\s\S]
\d [0-9]
\D [^0-9]
\w [A-Za-z0-9_]
\W [^A-Za-z0-9_]
\s 匹配一个空白符,包括空格、制表符、换页符、换行符和其他 Unicode 空格, [\f\n\r\t\v​\u00a0\u1680​\u180e\u2000​\u2001\u2002​\u2003\u2004​ \u2005\u2006​\u2007\u2008​\u2009\u200a​\u2028\u2029​​\u202f\u205f​ \u3000]
\S 匹配一个非空白符,[^ \f\n\r\t\v​\u00a0\u1680​\u180e\u2000​\u2001\u2002​\u2003\u2004​ \u2005\u2006​\u2007\u2008​\u2009\u200a​\u2028\u2029​\u202f\u205f​\u3000]
^ 匹配输入开始。如果多行(multiline)标志被设为 true,该字符也会匹配一个断行(line break)符后的开始处。
$ 匹配输入结尾。如果多行(multiline)标志被设为 true,该字符也会匹配一个断行(line break)符的前的结尾处。
\b 匹配一个零宽单词边界(zero-width word boundary),如一个字母与一个空格之间。例如,/\bno/ 匹配 "at noon" 中的 "no",/ly\b/ 匹配 "possibly yesterday." 中的 "ly"。
\B 匹配一个零宽非单词边界(zero-width non-word boundary),如两个字母之间或两个空格之间。例如,/\Bon/ 匹配 "at noon" 中的 "on",/ye\B/ 匹配 "possibly yesterday." 中的 "ye"。
(x) 匹配 x 并且捕获匹配项。 这被称为捕获括号(capturing parentheses)。例如,/(foo)/ 匹配且捕获 "foo bar." 中的 "foo"。被匹配的子字符串可以在结果数组的元素 [1], ..., [n]中找到,或在被定义的 RegExp 对象的属性 $1, ..., $9 中找到。捕获组(Capturing groups)有性能惩罚。如果不需再次访问被匹配的子字符串,最好使用非捕获括号(non-capturing parentheses)。
\n n 是一个正整数。一个反向引用(back reference),指向正则表达式中第 n 个括号(从左开始数)中匹配的子字符串。例如,/apple(,)\sorange\1/ 匹配 "apple, orange, cherry, peach." 中的 "apple,orange,"。
(?:x) 匹配 x 不会捕获匹配项。这被称为非捕获括号(non-capturing parentheses)。匹配项不能够从结果数组的元素 [1], ..., [n] 或已被定义的 RegExp 对象的属性 $1, ..., $9 再次访问到。
x*? 最小可能匹配
x+? 例如,/".*?"/ 匹配 '"foo" "bar"' 中的 '"foo"',而 * 后面没有 ? 时匹配 '"foo" "bar"'。
x(?=y) 仅匹配被y跟随的x。举个例子,/Jack(?=Sprat)/,如果"Jack"后面跟着sprat,则匹配之。`/Jack(?=Sprat
x(?!y) 仅匹配不被y跟随的x。举个例子,/\d+(?!\.)/ 只会匹配不被点.跟随的数字。/\d+(?!\.)/.exec('3.141') 匹配"141",而不是"3.141"
(?<=y)x x只有在y后面才匹配。'Benjamin Franklin is on the $100 €90 bill'.match(/(?<=\$)\d+/g) //["100"]
(?<!y)x x只有不在y后面才匹配。'it’s is worth about €90 $100'.match(/(?<!\$)\d+/g)//["90", "00"]

更多零宽断言相关

RegExp

RegExp 构造函数创建了一个正则表达式对象,用于将文本与一个模式匹配。

/pattern/flags
new RegExp(pattern [, flags])
RegExp(pattern [, flags])

pattern 正则表达式的文本。
flags 如果指定,标志可以具有以下值的任意组合:

  • g 全局匹配;找到所有匹配,而不是在第一个匹配后停止
  • i 忽略大小写
  • m 多行; 将开始和结束字符(^和$)视为在多行上工作(也就是,分别匹配每一行的开始和结束(由 \n 或 \r 分割),而不只是只匹配整个输入字符串的最开始和最末尾处。
  • u Unicode; 将模式视为Unicode序列点的序列
  • y 粘性匹配; 仅匹配目标字符串中此正则表达式的lastIndex属性指示的索引(并且不尝试从任何后续的索引匹配)。
  • s dotAll模式,匹配任何字符(包括终止符 '\n')。
var regex = new RegExp('xyz', 'i');
// 等价于
var regex = /xyz/i;

var regex = new RegExp(/xyz/i);
// 等价于
var regex = /xyz/i;

支持传变量

/ab+c/i;

# 字面量
new RegExp('ab+c', 'i');

# 构造函数
new RegExp(/ab+c/, 'i');

当使用构造函数创造正则对象时,需要常规的字符转义规则(在前面加反斜杠 \)。

new RegExp("\\w+");

String.prototype.replace()

replace() 方法返回一个由替换值(replacement)替换一些或所有匹配的模式(pattern)后的新字符串。模式可以是一个字符串或者一个正则表达式, 替换值可以是一个字符串或者一个每次匹配都要调用的函数。
原字符串不会改变。
str.replace(regexp|substr, newSubStr|function)

替换字符串可以插入的特殊变量名:

变量名 | 代表的值

  •         |-
    

$$ | 插入一个 "$"。
$& | 插入匹配(一般是括号里的匹配)的子串。
$` | 插入当前匹配的子串左边的内容。
$' | 插入当前匹配的子串右边的内容。
$n | 假如第一个参数是 RegExp对象,并且 n 是个小于100的非负整数,那么插入第 n 个括号匹配的字符串。

函数的参数:

变量名 代表的值
match 匹配的子串。(对应于上述的$&。)
p1,p2, ... 假如replace()方法的第一个参数是一个RegExp 对象,则代表第n个括号匹配的字符串。(对应于上述的$1,$2等。)
offset 匹配到的子字符串在原字符串中的偏移量。(比如,如果原字符串是“abcd”,匹配到的子字符串是“bc”,那么这个参数将是1)
string 被匹配的原字符串。
function replacer(match, p1, p2, p3, offset, string) {
  // p1 is nondigits, p2 digits, and p3 non-alphanumerics
  return [p1, p2, p3].join(' - ');
}
var newString = 'abc12345#$*%'.replace(/([^\d]*)(\d*)([^\w]*)/, replacer);
console.log(newString);  // abc - 12345 - #$*%

RegExp.prototype.test()

执行一个检索,用来查看正则表达式与指定的字符串是否匹配。返回 true 或 false。
regexObj.test(str)

当想要知道一个模式是否存在于一个字符串中时,就可以使用 test()(类似于 String.prototype.search() 方法),差别在于test返回一个布尔值,而 search 返回索引(如果找到)或者-1(如果没找到);

如果正则表达式设置了全局标志gtest() 的执行会改变正则表达式lastIndex属性。连续的执行test()方法,后续的执行将会从 lastIndex 处开始匹配字符串,(exec() 同样改变正则本身的 lastIndex属性值).

var regex = /foo/g;

// regex.lastIndex is at 0
regex.test('foo'); // true

// regex.lastIndex is now at 3
regex.test('foo'); // false

String.prototype.match()

match() 方法检索返回一个字符串匹配正则表达式的的结果。
str.match(regexp)

如果使用g标志,则将返回与完整正则表达式匹配的所有结果,但不会返回捕获组。

如果未使用g标志,则仅返回第一个完整匹配及其相关的捕获组(Array)。
在这种情况下,返回的项目将具有如下所述的其他属性。

  • groups: 一个捕获组数组 或 undefined(如果没有定义命名捕获组)。
  • index: 匹配的结果的开始位置
  • input: 搜索的字符串.

如果未找到匹配则为null。

不包含 g 标志,str.match() 将返回与 RegExp.exec(). 相同的结果。

    let str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';

    let a = str.match(/[A-E]/gi);
    console.log(a);
    // ['A', 'B', 'C', 'D', 'E', 'a', 'b', 'c', 'd', 'e']

    let b = str.match(/[A-E]/i);
    console.log(b);
    // 0: "A"
    // groups: undefined
    // index: 0
    // input: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
    // length: 1

如果你需要知道一个字符串是否与一个正则表达式匹配 RegExp ,可使用 test()
如果你只是需要第一个匹配结果,你也可以使用 RegExp.exec()
如果你想要获得捕获组,并且设置了全局标志,你需要用 RegExp.exec()

RegExp.prototype.exec()

exec() 方法在一个指定字符串中执行一个搜索匹配。返回一个结果数组或 null。
如果你只是为了判断是否匹配(true或 false),可以使用 RegExp.test() 方法,或者 String.search() str.search(regexp) 方法。
regexObj.exec(str)

当正则表达式使用 g 标志时,可以多次执行 exec 方法来查找同一个字符串中的成功匹配。
当你这样做时,查找将从正则表达式的 lastIndex 属性指定的位置开始。(test() 也会更新 lastIndex 属性)。

    let str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    let aRe = /[A-E]/i;//不要对他进行循环,会陷入死循环
    let a = aRe.exec(str);
    console.log(a);
    // 0: "A"
    // groups: undefined
    // index: 0
    // input: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
    // length: 1

    let bRe = /[A-E]/ig;
    let b = bRe.exec(str);
    console.log(b);
    // 0: "A"
    // groups: undefined
    // index: 0
    // input: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
    // length: 1

    let bArr;
    while (bArr = bRe.exec(str)) {
      console.log(bArr);
      console.log(bRe.lastIndex);
      // ["B", index: 1, input: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", groups: undefined]
      // 0: "B"
      // groups: undefined
      // index: 1
      // input: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
      // length: 1
    }

相关代码

.*? .+?

    let x = '<a href="xxx"></a><>';

    let d = x.match(/<.*?>/g);
    console.log(d);//["<a href="xxx">", "</a>", "<>"]
    let e = x.match(/<.*>/g);
    console.log(e);//["<a href="xxx"></a><>"]

    let h = x.match(/<.+?>/g);
    console.log(h);//["<a href="xxx">", "</a>"]
    let i = x.match(/<.+>/g);
    console.log(i);//["<a href="xxx"></a><>"]

    let y = '"foo" "bar" ""';
    let f = y.match(/".+?"/g);
    console.log(f);//[""foo"", ""bar""]
    let g = y.match(/".+"/g);
    console.log(g);//[""foo" "bar" """]

匹配字符串中重复出现的内容

\n

\1 \2 的用法
正则表达式中的小括号() 是代表分组的意思。
如果再其后面出现\1则是代表与第一个小括号中要匹配的内容相同。
\2以此类推。


//这里会匹配得 aa bb cc 11 22 这种
/([a-zA-Z0-9])\1+/g

//这里会匹配 abba
/([a-z])([a-z])\2\1/

转换开始第N位到倒数第N位之间的字符

    let str = `abcde1fg3h24ijklmn`
    //let str = `abcdefghijklmn`;

    let res = str.replace(/(.{3})(.*)(.{3})/, function (match, p1, p2, p3) {
        return p1 + new Array(p2.length + 1).join('*') + p3;
    })

//另一种

    let res = str.replace(/(.{3}).*(.{3})/, '$1********$2');

match可用于统计出现次数

function derDieDas(wort) {
  var vowels = wort.match(/[aeiouäöü]/gi).length;
  if (vowels < 2) return `das ${wort}`;
  if (vowels < 4) return `die ${wort}`;
  return `der ${wort}`;
}

通过match判断a-z是否都出现过一次

    function isPangram(string){
        return (string.match(/([a-z])(?!.*\1)/ig) || []).length === 26;
    }

字符串不需要转换成数组就能进行遍历

function DNAStrand(dna) {
  return dna.replace(/./g, function(c) {
    return DNAStrand.pairs[c]
  })
}

实时给手机号打空格

也可以用在给钱加空格

'13012341234'.replace(/(^\d{3}|\d{4})(?=\d)/g,'$& ')

'13012341234'.replace(/\B(?=(\d{4})+$)/g,' ');

匹配某一个固定格式字符串后面的字符

        let str = "a_b_2_d_1"
        let result = str.match(/\B[a-z0-9]+/gi);
        console.log(result); //["b", "2", "d", "1"]


        let str = "a_b_2_d_1"
        let re = /(?:_)([a-z0-9]+)/gi
        let match
        let result = []
        while (match = re.exec(str)) {
            result.push(match[1])
        }
        console.log(result)//["b", "2", "d", "1"]

获取url里的全部参数

let url = "https://api.test.com/search?name=xxx&age=yyy&sex=zzz";
    
let reg = /\?.+/;
//let result = reg.exec(url)[0];
let result = url.match(reg)[0];

let result = '';
let index = url.indexOf('?');
if (index > 0) {
   result += url.substr(index);
}

console.log(result);

url参数解析方法

			function analysisUrlParams(url, name) {
				var reg = new RegExp('(^|&|/?)' + name + '=([^&]*)(&|$)', 'i');
				var result = url.match(reg);
				if (result) {
					return decodeURIComponent(result[2]);
				}
				return '';
			}
const q = {};
location.search.replace(/([^?&=]+)=([^&]+)/g,(_,k,v)=>q[k]=v);
console.log(q);

时间验证

/^([01]\d|2[0-3]):[0-5]\d$/.test('23:39') 

互换字母顺序

    var re = /(\w+)\s(\w+)/;
    var str1 = "John Smith";
    var newstr = str1.replace(re, "$2 $1");
    console.log(newstr);//Smith John

其他


[x] 后边不能直接用{x},要用就要加括号。


posted @ 2017-02-28 11:44  晴明桑  阅读(268)  评论(0编辑  收藏  举报