转载请注明出处:平行的博客原创排版链接:点击跳转系统学习正则表达式。在网上找了很多教程,其中《55分钟学会正则表达式》是翻译自网上的教程是最系统最详细的,整个正则表达式的学习大概需要两个小时。为什么要写这篇文章,因为我觉得如果这篇文章不是太生硬,废话多,排版乱,还有一些地方有错误,我觉得55分钟可以写完。于是重新整理了一下布局。学习工具是catlog|grep-E'pattern'正则表达式基本语法核心知识点正则表达式由只代表自身的字面值和代表特定含义的元字符组成。文字:意味着他们寻找自己的元字符:一些模式匹配句点。A。表示匹配任何单个字符。下面的正则表达式c.t的意思是:先找到c,然后找到任意单个字符,再找到t。会找到cat、cot甚至字符串文字c.t,但不会找到ct或coot。反斜杠\如果用反斜杠转义,任何元字符都会变成文字。所以上面的正则表达式c\.t可以匹配到文本c.t文本a\h,通过a\\h可以找到字符类(Characterclasses)的定义:方括号中的字符集。意思是:找出其中任意一个字符。正则表达式c[aeiou]t表示“找到c后跟一个元音,然后找到t”。会匹配到cat正则表达式[0123456789]表示找一个数字正则表达式[a]与a含义相同:"finda"一些转义例子:\[a\]表示文本[a][\[\]ab]表示匹配a[or]oraorb。[\\[\]]表示“匹配一个\或[或]注意:有些字符在字符类内部充当元字符,但在字符类之外充当字面值。例如:连字符——有些字符做相反的事情例如:.表示“匹配任何字符”,但是[.]表示“匹配句号”。有些字符在这两种情况下都是元字符,但它们在每种情况下代表不同的含义。字符类范围(ranges)可以使用字符类中的连字符表示字母或数字的范围_:[b-f]和[bcdef]表示[A-Z]和[ABCDEFGHIJKLMNOPQRSTUVWXYZ]均表示“匹配大写字母”。[1-9]和[123456789]均表示“匹配一个非零数字”。区间和单个字符可以在同一个字符类中共存:[0-9.,]表示“匹配数字或a.或a,”。[0-9a-fA-F]表示“匹配一个十六进制数”。[a-zA-Z0-9\-]表示“匹配字母数字字符或-”。注意:您可以尝试以非字母数字字符(例如abc[!-/])结束间隔,但这在其他实现中可能在句法上不正确。即使语法正确,也很难看出这个区间包含哪些字符。请不要重蹈覆辙,区间端点的范围要一致。即使像[A-z]这样的表达式在您选择的实现中是合法的,它也可能不会执行您希望它执行的操作。注意。区间是字符区间,不是数字区间。正则表达式[1-31]的意思是找一个1或者一个2或者一个3,而不是找一个从1到31的整数。字符类否定(negation)可以在最前面用^排除一个字符类开始。[^a]表示“匹配除a以外的任何字符”。[^a-zA-Z0-9]表示“查找非字母数字字符”。[\^abc]表示“找到一个^或a或b或c”。[^\^]表示“查找除^以外的任意字符”字符类补充\d的意思与[0-9]:“匹配一个数字”一致。\w的含义与[0-9A-Za-z_]一致:“匹配一个单词字符,(字母或数字或下划线或汉字)”。\s表示“匹配任何空白字符(空格、制表符)”。\s+可以表示回车换行\D同[^0-9]:“匹配任何非数字字符”。\W同[^0-9A-Za-z_]:“匹配任何非单词字符(译者注:匹配任何不是字母、数字、下划线、汉字的字符)”。\S表示“匹配任何非空格的字符”。\t表示制表符[\u4e00-\u9fa5]表示中文和英文[^\x00-\xff]匹配双字节字符,中文也是双字节字符,排除英文乘数(Multipliers)可以用字面量值或字符类后跟大括号以使用乘数。正则表达式a{1}与a相同,意思是“匹配一个a”。\d{3}表示3个相连的数字。a{0}表示“匹配空字符”。a\{2\}表示文本a{2}。大括号在字符类中没有特殊含义。[{}]表示“匹配a{或}。乘数没有记忆。[abc]{2}表示“匹配aorborc,然后匹配aorborc。这与匹配aa或bb或cc不同!乘数区间x{4,4}与x{4}相同。colou{0,1}r表示“匹配颜色或颜色。a{3,5}表示“匹配aaaaa或aaaa或aaa”。a{1,}表示“在列中找到一个或多个a”。但是你multiplierof会贪心,找到第一个a后,会匹配尽可能多的a。..{0,}表示“匹配任何大小写”。不管你输入的文本是什么-即使是空注:匹配较长者优先,因为乘法器是贪心的,如果你输入文本Ihadanaaaaawfulday,正则表达式会匹配aaaaainaaaaawful,不会在第三个a之后停止匹配,乘法器会在找到第一个文本时停止。如果你输入的文本是Ihadanaaawfuldaaaaay,那么这个正则表达式会在第一场匹配中找到aaainaaawful只有当你说“findmeanothermatch”时,它才会继续搜索并在daaaaay中找到aaaaa乘数补码?与{0,1}的含义相同。例如colou?r表示“匹配颜色或颜色”。*等于{0,}。例如*表示“匹配所有内容”,如上所述。+等于{1,}。例如,\w+表示匹配至少一个或多个单词。[0-9]+表示匹配至少一个或多个数字\?\*\+表示?*+。[?*+]表示找一个?或*或+。Lazy(Non-greed)前面提到的乘法过滤器是贪心的,加法可以消除贪心特征吗?\d{4,5}?它将等于\d{4},并在找到合适的文本后停止。“。*?”表示“匹配双引号,后跟尽可能少的字符,后跟双引号”。这实际上很有用。交替您可以使用管道符号来匹配多个选项:cat|dog表示“匹配猫或狗”。红|蓝|和red||blue和|red|blue具有相同的含义,“匹配红色或蓝色或空字符串”。a|b|c与[abc]相同。猫|狗|\|意思是“匹配猫或狗或管道符号”。[cat|dog]意思是“找到aorcordordorgoroortorapipesymbol”。分组(Grouping)查找星期几,使用(Mon|Tues|Wednes|Thurs|Fri|Satur|Sun)日。(\w*)ility等同于\w*ility。两者的意思都是“找到以ility结尾的词”。为什么第一种形式更有用,后面你会看到...\(\)的意思是“匹配一个(之后,再匹配一个)”。[()]表示“匹配一个(或一个)”。单词边界(Wordboundaries)单词边界是单词字符和非单词字符之间的位置。请记住,单词字符是w,即[0-9A-Za-z_],非单词字符是W,即1。文本的开头和结尾始终被视为单词边界。输入文本it'sacat有八个单词边界。如果我们在cat后面追加一个空格,就会有九个单词边界。正则表达式\b表示“匹配单词边界”。\b\w\w\w\b表示“匹配三个字母的单词”。a\ba的意思是“找到a,遵循单词边界,然后找到a”。无论输入文本是什么,此正则表达式永远不会成功找到匹配项。单词边界不是字符。它们的宽度为零。以下正则表达式的意思相同:行边界每个文本块被分成一行或多行,由换行符分隔,如下所示:正则表达式^表示“匹配起始行”。正则表达式$表示“匹配行尾”。^$表示“匹配一个空行”。^.*$将匹配整个文本,并且由于换行符是一个字符,.会匹配它。要匹配单行,请使用惰性乘数^.?$和^.*?$。\^\$表示“匹配一个插入符号后跟一个美元符号”。[$]表示“匹配美元符号”。但是,[^]是非法的单个正则表达式。要记住的是,插入符号在方括号中时具有不同的特殊含义。要将插入符放在字符类中,请使用[\^]。与单词边界一样,行边界不是字符。它们的宽度为零。捕获和替换这就是正则表达式开始变得异常强大的地方。捕获组如您所知,括号用于表示组。它们也可用于捕获子字符串。如果正则表达式是一个微型计算机程序,这个捕获组将是它的(部分)输出。正则表达式(\w*)ility表示“查找以ility结尾的单词”。捕获组1是匹配部分内容的\w*。文本包含accessibility一词,捕获组1是accessib。文本仅包含ility,捕获组1为空字符串。您可以有多个捕获组,它们甚至可以嵌套。捕获组从左到右编号。只需计算左括号。假设我们的正则表达式是(\w+)hada((\w+)\w+)。如果我们的输入文本是Ihadaniceday,那么:capturegroup1isI.Capturegroup2isaniceday。捕获组3很好。在某些实现中,您可能有权访问捕获组0,即完整匹配项:我度过了愉快的一天。是的,这确实意味着括号有些重复。成功匹配返回的捕获组数始终等于原始正则表达式中的捕获组数。请记住这一点,因为它可以帮助您理解一些令人困惑的情况。正则表达式((cat)|dog)表示“匹配猫或狗”。这里总是有两组捕获组。如果我们的输入文本是狗,那么捕获组1是狗,捕获组2是空字符串,因为没有使用其他选择。正则表达式a(\w)*表示“匹配以a开头的单词”。始终只有一个捕获组(译者注:捕获组0除外):如果输入文本是a,则捕获组1为空字符串。如果输入文本是ad,捕获组1是d。如果输入文本是鳄梨,则捕获组1是鳄梨。替换使用正则表达式查找字符串后,您可以指定另一个字符串来替换它。第二个字符串的替换表达式。您可以在替换表达式中引用捕获组。这是您可以在替换表达式中做的唯一特别的事情,这意味着您不必完全破坏您刚刚发现的内容。假设您尝试将美国日期(MM/DD/YY)替换为ISO8691格式的日期(YYYY-MM-DD)。从正则表达式(\d\d)/(\d\d)/(\d\d)开始。请注意,这里有三个捕获组:月、日和两位数的年份。捕获组通过使用\和捕获组编号来引用。所以,您的替换表达式是20\3-\1-\2。如果我们的输入文本是03/04/05(表示2005年3月4日),那么:capturegroup1是03;捕获组2是04;捕获组3是05;您可以在替换表达式中添加更多子引用捕获组。必须转义替换表达式中的反斜杠。例如,您有一些文本用于计算机程序中的文字。这意味着您需要在普通文本中的每个双引号或反斜杠之前放置一个反斜杠。在正则表达式([\"])中,捕获组1是"或\。在替换表达式\\\1中,文字反斜杠后跟匹配的双引号或反斜杠。反向引用(Back-references)你可以在同一个表达式中引用同一个捕获组。这称为反向引用。表达式([abc])\1表示匹配aa或bb或cc。使用正则表达式编程过多的反斜杠综合症在某些编程语言中,例如Java,没有对包含正则表达式的字符串的特殊支持。字符串有自己的转义规则,这些规则与正则表达式的规则重叠,通常会导致反斜杠过载。例如(还是Java):要匹配一个数字,正则表达式\d变成Stringre="\d;"在源代码中。要匹配双引号字符串,"[^"]*"变为Stringre="\"[^\"]*\"";。要匹配反斜杠或左方括号或双方括号,正则表达式[\\\\[\\]]变为Stringre="[\\\\\\[\\]]";.字符串re="\s";和Stringre="[]";是相同的。注意不同的转义“优先级”。在其他编程语言中,正则表达式由特殊标记标识,通常是正斜杠/。下面是一些JavaScript示例:为了匹配数字,\d变成varregExp=/\d/;。匹配反斜杠或左方括号或右方括号,varregExp=/[\\\\[\\]]/;。varregExp=/\s/;与varregExp=/[]/;相同。当然,这意味着必须转义正斜杠,而不是双引号。匹配URL的前面部分:varregExp=/https?:\/\//;。基于此,我希望您理解为什么我一直向您提及反斜杠。练习题如下:将课文中的所有中文替换为中文写一个正则表达式来匹配1到31(含)之间的整数。双引号内不包含"的所有文本双引号内的所有文本答案:##查找:(_)([^\x00-\xff]+)+(_)##替换`\*\*\2\*\*`[1-9]|[12][0-9]|3[01]cat日志|grep-E'"[^"]{0,}"'cat日志|grep-E'".{0,}"'练习草稿我今天过得很愉快,aa!b90"我爱你,玛丽!""我爱你","嘿"foodz...zabcdgeiecieacc[abc]at2016-10-2212:12:12catc.tc\.t[a]文本编辑器中的其他偏移量(Offsets)会开始搜索你光标所在的位置。编辑器将开始向前搜索文本,并在第一个匹配处停止。下一次搜索从第一次搜索完成位置的右侧开始。编程时,需要文本的偏移量。这个偏移量将在代码中被明确支持,或者存储在一个包含文本的对象中(比如Perl),或者一个包含正则表达式的对象(比如JavaScript)。(在Java中,这是一个由正则表达式和复合对象组成的字符串。)在任何情况下,默认值>0,表示文本的开始。搜索后,偏移量会自动更新,或作为输出的一部分返回。不管怎样,通常很容易使用循环来解决这个问题。请注意,正则表达式完全有可能匹配空字符串。您可以立即实施的一个简单示例是{0},在这种情况下,新偏移量等于旧偏移量,从而导致无限循环。某些实现可能会保护您免受这些情况的影响,但请查看相应的文档。动态正则表达式动态构造正则表达式字符串时必须小心。如果您使用的字符串不固定,它可能包含意外的元字符。这会导致语法错误。更糟糕的是,它可能会产生一个语法正确的正则表达式,但行为却出乎意料。有bug的Java代码:Stringsep=System.getProperty("file.separator");String[]directories=filePath.split(sep);这个错误是:String.split()认为sep是一个正则表达式。但在Windows下,sep是字符串\。这不是一个语法正确的正则表达式。结果是:异常PatternSyntaxException。任何优秀的编程语言都提供了一种转义字符串中出现的所有元字符的机制。在Java中,您可以这样做:Stringsep=System.getProperty("file.separator");String[]directories=filePath.split(Pattern.quote(sep));电子邮件地址不要使用正则表达式来验证电子邮件地址。首先,很难做到这一点。电子邮件地址确实匹配正则表达式,但它又长又复杂,让人联想到世界末日。任何缩写都可能产生假阴性。(你知道吗?电子邮件地址可以包含评论!)其次,即使提供的电子邮件地址与正则表达式匹配,也不能证明它的存在。验证电子邮件地址的唯一方法是通过电子邮件发送。标记在实际应用程序中,不要使用正则表达式来解析HTML或XML。使用简单的正则表达式解析HTML/XML是不可能的,而且通常很难解决这个问题。最好找到一个现有的解析库来为您执行此操作。部分场景替换Hostsegmentfault.comConnectionkeep-aliveContent-Length55Accept*/*Originhttps://segmentfault.comX-Requested-WithXMLHttpRequestUser-AgentMozilla/5.0(Macintosh;IntelMacOSX10_11_6)AppleWebKit/537.36(KHTML,like壁虎)Chrome/61.0.3163.100Safari/537.36^(\S+)(\s+)(.{0,})"\1":"\3","主机":"segmentfault.com","连接":“保持活动”,“内容长度”:“55”,“接受”:“*/*”,“来源”:“https://segmentfault.com”,“X-Requested-With”:“XMLHttpRequest","User-Agent":"Mozilla/5.0(Macintosh;IntelMacOSX10_11_6)AppleWebKit/537.36(KHTML,likeGecko)Chrome/61.0.3163.100Safari/537.36",文本块换行匹配---layout:posttags:-linux------(\n(.{0,}))*---参考网站55分钟学习正则表达式(翻译)0-9A-Za-z_?
