20分钟学会正则表达式

Posted 代码的荣耀

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了20分钟学会正则表达式相关的知识,希望对你有一定的参考价值。

程序员的世界有个笑话,在你遇到困难并决定使用正则表达式的时候,你会发现你又多了个困难。正则表达式是个非常强大的工具,老练的程序员常把它当作最后的杀手锏,一旦使用,必会技惊四座。


正则表达式是一种专门用于定义文本的模式匹配规则的语言(英文称作Regular Expressions,现在计算机界更正规的术语是regex-es)。正则表达式有自己的语法和语法规则,初学者使用起来极易出错,但它的价值使你不能不学。以下是个精简版的教程:

20分钟学会正则表达式

1、匹配单个字符

所有的编程语言都有自己的一套定义和使用正则表达式的方法,尽管各有不同,但本文所列的部分几乎适用于所有场合。这些例子使用javascript编写,可在浏览器中运行。


最基本的正则表达式是匹配单个字符,规则如下:

  • 点(.)匹配任何字符,如果想要匹配(.),需要用到转义字符(\)

  • 问号(?)表示其前面的字符是可选的,如果想要匹配(?),同样需要用到转义字符(\)


示例:


var text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit lest. Donec convallis dignissim ligula, et rutrum est elat vistibulum eu.';

/*
 *将会匹配"elit"和"elat",点可匹配任何字符
 *修饰符"g"表示全局模式,即模式将会被应用于所有的字符串,而
 *不是在发现第一个匹配项时立即停止。
 *如果去掉g,改为(var regex = /el.t/;),则只会匹配"elit"。
 */

var regex = /el.t/g;
console.log( text.match(regex) );


/*
 *将会匹配"est"和"lest"
 *问号使得"l"是可选的
 */

var regex2 = /l?est/g;
console.log( text.match(regex2) );

程序的运行结果为:

[“elit”,”elat”] 
[“lest”,”est”]

20分钟学会正则表达式

2、匹配一组字符

基于前面的示例,我们还可以使用集合来匹配一组特定字符:

  • 集合是置于中括号内的一个或多个字符,比如[abc],它将仅匹配其中的一个字符,此例中只会匹配a或b或c。也可以使用^来否定一组字符,例如[^abc]将会匹配除abc外的任何字符。也可以指定集合的范围,例如[0-9]、[a-z],将会匹配该范围内的所有字符。

  • 正则表达式拥有一些内置集合,来帮助我们快速书写正则表达式。例如[0-9]可以写作 \d ,[^0-9]可以写作 \D。还有一些用于单词字符的集合,例如:匹配a到z及数字和下划线—— \w 和 \W(与\d、\D类似,大写表示“非”);匹配空格包括制表符和换行符——\s 和 \S。


看如下示例:


var text = 'cat car can';

//匹配"cat" 和 "can"
console.log( text.match(/ca[tn]/g) );

//匹配"car",注意^
console.log( text.match(/ca[^tn]/g) );


//这个示例演示匹配数字
text = 'I would like 8 cups of coffee, please.';

//匹配text中的数字,此处为8
console.log('How many cups: ' + text.match( /[0-9]/g ));

//更精简的写法是使用  \d
console.log('How many cups: ' + text.match( /\d/g ));

//匹配除数字外的所有字符,将返回一个非数字数组
console.log( text.match(/\D/g) );

程序运行结果如下:

["cat","can"]

["car"]

How many cups: 8

How many cups: 8

["I"," ","w","o","u","l","d"," ","l","i","k","e"," "," ","c","u","p","s"," ","o","f"," ","c","o","f","f","e","e",","," ","p","l","e","a","s","e","."]

20分钟学会正则表达式

3、匹配单词

大多数时候,我们需要匹配整个单词,而不是单个字符,可通过如下的修饰符来完成的这项匹配,这些修饰符用来重复匹配一个字符或字符集:

  • +,匹配前面的字符或字符集一次或多次;

  • *,匹配前面的字符或字符集0次或多次;

  • {x},表示匹配前面的字符或字符集x次,{x,}表示至少匹配x次,{x, y}表示匹配x-y次;


\b模式比较特殊,用于匹配单词边界,也就是指单词和空格间的位置。例如,“\bh”可以匹配“one hour”中的“h”,但不能匹配“match”中的“h”。


看如下示例:


var text = 'Hello people of 1974. I come from the future. In 2020 we have laser guns, hover boards and live on the moon!';

//匹配句中的年份,\d+可匹配一个或多个数字
var yearRegex = /\d+/g;
console.log('Years: ', text.match( yearRegex ) );

//匹配所有以大写字母开头,句号或感叹号结尾的句子
/*
 *问号表示匹配模式是非贪婪的
 *非贪婪模式尽可能少的匹配所搜索的字符串
 *默认的贪婪模式则尽可能多的匹配所搜索的字符串
 *若此处去掉?,则匹配结果是整个text
 */

var sentenceRegex = /[A-Z].+?(\.|!)/g;
console.log('Sentences: ', text.match(sentenceRegex) );

//找到所有以h开头的单词,i修饰符表示不区分大小写
//g修饰符前面已经提过
/*
 * \b 匹配单词边界
 * 若去掉则单词the中的he也会被匹配到
 */

var hWords = /\bh\w+/ig;
console.log('H Words: ', text.match(hWords) );

//找出所有长度为4-6的单词
var findWords = /\b\w{4,6}\b/g;
console.log( 'Words between 4 and 6 chars: ', text.match(findWords) );

//找出所有长度大于5的单词
console.log( 'Words 5 chars or longer: ', text.match(/\b\w{5,}\b/g) );

//找出所有长度为6的单词
console.log( 'Words exactly 6 chars long: ', text.match(/\b\w{6}\b/g) );

程序运行结果如下:

Years: ["1974","2020"]

Sentences: ["Hello people of 1974.","I come from the future.","In 2020 we have laser guns, hover boards and live on the moon!"]

H Words: ["Hello","have","hover"]

Words between 4 and 6 chars: ["Hello","people","1974","come","from","future","2020","have","laser","guns","hover","boards","live","moon"]

Words 5 chars or longer: ["Hello","people","future","laser","hover","boards"]

Words exactly 6 chars long: ["people","future","boards"]

20分钟学会正则表达式

4、匹配/校验整行

在JavaScript中,这种模式会被呗用来验证用户输入的文本字段。除了使用^开头(行开头),结尾(行结尾),其他与一般正则表达式没有什么区别。开头结尾将保证模式跨越整个文本长度,而不只是匹配其中的一部分。


此外,这种情况下我们可以使用正则对象的test()方法来测试字符串是否匹配,匹配则返回true,否则返回false。


看如下示例:


//下面是一组字符串,我们来提取出其中的URL
var strings = [
    'http://tutorialzine.com/posts/',
    'this is not a URL',
    'https://google.com/',
    '123461',
    'http://tutorialzine.com/?search=jquery',
    'http://not a valid url',
    'abc http://invalid.url/'
];

//下面这个简单的正则表达式即可完成这项工作
//^开头$结尾表示整个字符串必须都匹配,而不是只有一部分能匹配
var regex = /^https?:\/\/[\w\/?.&-=]+$/;

var urls = [];
forvar i = 0; i < strings.length; i++ ){
    if( regex.test(strings[i]) ){       
        urls.push(strings[i]);
    }
}

console.log('Valid URLs: ', urls);

程序运行结果如下:

Valid URLs:[“http://tutorialzine.com/posts/“,”https://google.com/“,”http://tutorialzine.com/?search=jquery“]

20分钟学会正则表达式

5、查找和替换

正则表达式另一个常见的应用场景是文本的查找和替换,注意两个基本概念:

  • 组(group):一组置于小括号()中的模式,每个组将捕获并保存与其中模式匹配的文本,这些文本可以通过索引进行访问,从1开始,1表示第一组。

  • 反向引用:在表达式中也可以反向引用组——反斜杠后跟组索引,从\1开始,只有捕获了文本后,\x中的内容才能确定。见下面的示例,这个功能很少使用,你可以忽略它。


看如下示例:


// 使用反向引用,
// 找出仅由相同字母组成的单词
var text = 'Abc ddefg, hijk lllll mnopqr ssss. Tuv wxyyy z.';
var sameLetterRegex = /\b(\w)\1*\b/g;
console.log( text.match(sameLetterRegex) );

//将"John Smith" 替换为"Smith, John"
//每个组(\w+)匹配一个单词
//可通过索引$访问
var name = 'John Smith';
var nameRegex = /(\w+) (\w+)/;
console.log( name.replace(nameRegex, '$2, $1') );

//对于更高级的操作,我们需要提供JS回调
//例如下面将姓变为大写
var upcasename = name.replace(nameRegex, function(string, group1, group2){
    return group2.toUpperCase() + ', ' + group1;
});
console.log( upcasename );

程序运行结果如下:

[“lllll”,”ssss”,”z”] 
Smith, John 
SMITH, John

20分钟学会正则表达式

更多资源推荐和深入阅读

如果你读完并掌握了本文中的内容,差不多就可以解决80%正则表达式相关的问题。以下是一些有用的学习资源和工具,可以帮助你更深入地学习:

  • RegexOne互式正则表达式教程——https://regexone.com/

  • Mozilla有关JavaScript正则表达式的文章——https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions

  • Regexr可视化正则表达式调试与测试工具——http://regexr.com/

  • regex101另一个优秀的正则表达式测试工具——https://regex101.com/

  • regular-expressions.info上的更多内容和技术细节(需翻墙访问)——http://www.regular-expressions.info/

  • JavaScript的正则表达式仅适用于拉丁字母,若要支持unicode,请参看——http://stackoverflow.com/questions/280712/javascript-unicode-regexes


20分钟学会正则表达式
20分钟学会正则表达式

不关注



就捣蛋


以上是关于20分钟学会正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

55分钟学会正则表达式

55分钟学会正则表达式

三分钟学会简单的正则表达式

学会Linux正则表达式,我只用了3分钟

5分钟包你学会正则表达式

5分钟包你学会正则表达式