【正则表达式】为那些需要刷新记忆的人准备,不适合新手

正则表达式示例

1.1 正则表达式语法总结

  • 字符:除了在正则表达式中具有特殊含义的字符外,所有字符都与自身匹配。例如,正则表达式x匹配子字符串"x";正则表达式9匹配"9";正则表达式=匹配"=“;和正则表达式@匹配”@"。
  • 特殊正则表达式字符:这些字符在正则表达式中具有特殊含义(将在下面讨论):., +, *, ?, ^, $, (, ), [, ], {, }, |, \。
  • 转义序列(\char)
    • 要匹配正则表达式中具有特殊含义的字符,需要使用带有反斜杠 ( ) 的转义序列前缀。例如,.火柴".“;正则表达式+匹配”+“;和正则表达式(匹配”("。
    • 还需要使用正则表达式\来匹配""(反斜杠)。
    • 正则表达式可识别常见的转义序列,例如\n换行符、制表\t符\r、回车符、\nnn最多3 位八进制数、\xhh两位十六进制代码、\uhhhh4 位 Unicode、\uhhhhhhhh8 位 Unicode。
  • 字符序列(或字符串):可以通过组合字符序列(称为子表达式)来匹配字符串。例如,正则表达式Saturday匹配"Saturday". 默认情况下,匹配区分大小写,但可以通过 修饰符设置为不区分大小写。
  • OR 运算符 ( | ):例如,正则表达式four|4接受字符串"four"or “4”。
  • 字符类(或括号列表)
    • […] :接受方括号内的任意一个字符,例如[aeiou]匹配"a"、“e”、"i"或。“o”“u”
    • [.-.] (范围表达式):接受范围中的任意一个字符,例如[0-9]匹配任意数字;[A-Za-z]匹配任何大写或小写字母。
    • [ ^ …]:不是一个字符,例如,[^0-9]匹配任何非数字。
    • 只有这四个字符需要在括号列表内转义序列:^, -, ], \。
  • 出现指示符(或重复运算符)
    • +:一个或多个( 1+),例如[0-9]+匹配一个或多个数字,例如’123’,,‘000’。
    • *:零个或多个 ( 0+),例如,[0-9]*匹配零个或多个数字。它接受所有的[0-9]+加上空字符串。
    • ?:零或一(可选),例如,[±]?匹配可选的"+“、”-"或空字符串。
    • {m,n} :m至n(包含两者)
    • {m}:精确的m时间
    • {m,} :m或更多 ( m+)
  • 元字符:匹配一个字符
    • .(点):除换行符之外的任何一个字符。与…一样[^\n]
    • \d、\D:任何一位数字/非数字字符。数字是[0-9]
    • \w、\W:任何一个单词/非单词字符。对于 ASCII,单词字符是[a-zA-Z0-9_]
    • \s、\S:任何一个空格/非空格字符。对于 ASCII,空白字符是[ \n\r\t\f]
  • 位置锚点:不匹配字符,而是匹配位置,例如行首、行尾、词首和词尾。
    • ^、 :分别为行首和行尾。例如 , [ 0 − 9 ] :分别为行首和行尾。例如,^[0-9] :分别为行首和行尾。例如[09]匹配数字字符串。
    • \b:单词边界,即单词开头或单词结尾。例如,匹配输入字符串中的\bcat\b单词。“cat”
    • \B: \b 的逆,即非单词开头或非单词结尾。
    • < , >:分别为词首和词尾,类似于\b. 例如,匹配输入字符串中的<cat>单词。“cat”
    • \A、\Z:分别是输入开始和输入结束。
  • 带括号的反向参考文献
    • 使用括号( )创建反向引用。
    • 使用$1, $2, …(Java、Perl、JavaScript)或\1, \2, … (Python) 按顺序检索向后引用。
  • 惰性(抑制重复运算符的贪婪):*?, +?, ??, {m,n}?,{m,}?

1.2 示例:数字[0-9]+或\d+

  1. regex(正则表达式)由一系列子表达式组成。在此示例中,[0-9]和+.
  2. 称为字符类(或[…]括号列表),包含字符列表。它匹配列表中的任何单个字符。在此示例中,匹配 0 到 9之间的任何单个字符(即数字),其中破折号 ( ) 表示范围。[0-9]-
  3. 称为出现指示符(或重复运算符),指示前一个子表达式出现一次或多次 ( ) +。在这种情况下,匹配一位或多位数字。1+[0-9]+
  4. 正则表达式可以匹配输入的一部分(即子字符串)或整个输入。事实上,它可以匹配输入的零个或多个子字符串(使用全局修饰符)。
  5. 此正则表达式匹配输入的任何数字子字符串(数字 0 到 9)。举些例子:
    - 如果输入为"abc123xyz",则匹配子字符串"123"。
    -. 如果输入为"abcxyz",则不匹配任何内容。
    -. 如果输入为"abc00123xyz456_0",则它匹配子字符串"00123"、“456"和"0”(三个匹配)。
  6. 请注意,此正则表达式将数字与前导零匹配,例如"000"、“0123"和"0001”,这可能是不可取的。
  7. 您还可以编写\d+,其中\d称为匹配任何数字的元字符(与相同[0-9])。编写正则表达式的方法不止一种!请注意,许多编程语言(C、Java、JavaScript、Python)使用反斜杠\作为转义序列的前缀(例如,\n换行符),您需要"\d+"改为编写。

1.3 代码示例(Python、Java、JavaScript、Perl)

Python

# 在 Python 命令行解释器下测试
$ python3
......
>>> import re    # 正则表达式需要模块're'

# 尝试查找: re.findall( regexStr , inStr ) -> matchedSubstringsList 
# r'...' 表示忽略转义码的原始字符串,即 r'\n' 是 '\'+'n' 
>>> re. findall(r'[0-9]+', 'abc123xyz') 
['123']    # 返回匹配子串的列表
>>> re.findall(r'[0-9]+', 'abcxyz')
[]
>>> re.findall(r'[0-9]+', 'abc00123xyz456_0')
['00123', '456', '0']
>>> re.findall(r'\d+', 'abc00123xyz456_0')
['00123', '456', '0']

# 尝试替换: re.sub( regexStr , replacementStr , inStr ) -> outStr 
>>> re.sub(r'[0-9]+', r'*', 'abc00123xyz456_0')
'abc*xyz*_*'

# 尝试用 count 替换: re.subn( regexStr , replacementStr , inStr ) -> ( outStr , count ) 
>>> re.subn(r'[0-9]+', r'*', 'abc00123xyz456_0') 
( 'abc*xyz*_*', 3)    # 返回输出字符串和计数的元组

Java

导入java.util.regex.Pattern;
导入java.util.regex.Matcher;

公共类TestRegexNumbers {
   公共静态无效主(字符串[] args){

      字符串 inputStr = "abc00123xyz456_0";  // 匹配的输入字符串
      String regexStr = "[0-9]+";            // 需要匹配的正则表达式

      // 步骤1:通过静态方法Pattern.compile()编译正则表达式,默认区分大小写
      Pattern pattern = Pattern.compile(regexStr) ;
      // Pattern.compile(regex, Pattern.CASE_INSENSITIVE); // 不区分大小写的匹配

      // 步骤 2:从编译的正则表达式模式中分配一个匹配引擎,
      // 并绑定到输入字符串
      Matcher matcher = pattern.matcher(inputStr) ;

      // 步骤 3:执行匹配并处理匹配结果
      // 尝试 Matcher.find(),它会查找下一个匹配
      while ( matcher.find() ) {
         System.out.println("find() 找到子字符串 \"" + matcher.group() 
               + "\" 从索引 " + matcher.start() + " 开始并在索引 " + matcher.end()
               结束);
      }

      // 尝试 Matcher.matches(),它尝试匹配整个输入 (^...$) 
      if ( matcher.matches() ) {
         System.out.println("matches()找到子字符串\"" + matcher.group()
               + "\" 从索引 " 开始 + matcher.start()
               + " 并以索引结尾 " + matcher.end());
      } 别的 {
         System.out.println("matches() 没有找到任何结果");
      }

      // 尝试 Matcher.lookingAt(),它尝试从输入的 START 开始匹配 (^...) 
      if ( matcher.lookingAt() ) {
         System.out.println("lookingAt()找到子字符串\"" + matcher.group()
               + "\" 从索引 " 开始 + matcher.start()
               + " 并以索引结尾 " + matcher.end());
      } 别的 {
         System.out.println("lookingAt() 没有发现任何结果");
      }

      // 尝试 Matcher.replaceFirst(),它替换第一个匹配项
      字符串替换Str = "**";
      String outputStr = matcher.replaceFirst(replacementStr) ; // 仅第一个匹配
      System.out.println(outputStr);

      // 尝试 Matcher.replaceAll(),它会替换所有匹配项
      替换Str =++”;
      输出Str = matcher.replaceAll(replacementStr) ; // 所有匹配
      System.out.println(outputStr);
   }
}

输出是:

find() 找到从索引 3 开始到索引 8 结束的子字符串“00123”
find() 找到从索引 11 开始到索引 14 结束的子字符串“456”
find() 找到从索引 15 开始到索引 16 结束的子字符串“0”
matches() 没有找到任何内容
LookingAt() 没有发现任何东西
abc**xyz456_0
abc++xyz++_++

Perl

Perl 广泛使用具有许多内置语法和运算符的正则表达式。在 Perl(和 JavaScript)中,正则表达式由一对正斜杠(默认)分隔,格式为. 您可以使用内置运算符:/regex/

  • m/ regex / modifier或/ regex / modifier:匹配regex. m是可选的。
  • s/正则表达式/替换/修饰符:用替换替换匹配的子字符串。

在 Perl 中,可以使用单引号非插值字符串’…'编写正则表达式以禁用\Perl 对反斜杠 ( ) 的解释。

#!/usr/bin/env perl
使用严格;
使用警告;

我的 $inStr = 'abc00123xyz456_0';  # 输入字符串
my $regex = '[0-9]+';            # 非插值字符串中的正则表达式模式字符串

# 尝试匹配 /regex/modifiers (或 m/regex/modifiers) 
my @matches = ( $inStr =~ /$regex/g );  # 将 $inStr 与带有全局修饰符的正则表达式匹配
                                      # 将所有匹配项存储在数组中
print "@matches\n";   # 输出:00123 456 0

while ( $inStr =~ /$regex/g ) {
    # 内置数组变量 @- 和 @+ 保留
   匹配的开始和结束位置 #,其中 $-[0] 和 $+[0] 是完全匹配,
   # $-[n] 和 $+[n] 用于反向引用 $1、$2 等。 
   print substr($inStr, $-[0], $+[0] - $-[0]), ',';   # 输出:00123, 456, 0,
}
打印“\n”;

# 尝试替换 s/regex/replacement/modifiers 
$inStr =~ s/$regex/**/g ;    # 使用全局修饰符
print "$inStr\n";           # 输出:abc**xyz**_**

JavaScript

<!DOCTYPE html>
 <!-- JSRegexNumbers.html -->
<html lang="en">
<>
<元字符集=“utf-8>
<title>JavaScript 示例:正则表达式</title>
<脚本>
var inStr = "abc123xyz456_7_00";

// 使用 RegExp.test(inStr) 检查 inStr 是否包含模式
console.log(/[0-9]+/.test(inStr));  // 真的

// 使用 String.search(regex) 检查字符串是否包含模式
// 返回匹配子字符串的起始位置,如果没有匹配则返回 -1 
console.log(inStr.search(/[0-9]+ /));  // 3

// 使用 String.match() 或 RegExp.exec() 查找匹配的子字符串、
// 反向引用和字符串索引
console.log(inStr.match(/[0-9]+/));  // ["123", 输入:"abc123xyz456_7_00", 索引:3, 长度:"1"] 
console.log(/[0-9]+/.exec(inStr));   // [“123”,输入:“abc123xyz456_7_00”,索引:3,长度:“1”]

// 使用 g(全局)选项
console.log(inStr.match(/[0-9]+/g));  // [“123”,“456”,“7”,“00”,长度:4]

// 带 g 标志的 RegExp.exec() 可以重复发出。
// 在最后找到的位置(在属性 RegExp.lastIndex 中维护)之后继续搜索。
var 模式 = /[0-9]+/g;
变量结果;
while (结果=pattern.exec(inStr)) {
   控制台.log(结果);
   console.log(pattern.lastIndex);
      // [“123”],6 
      // [“456”],12 
      // [“7”],14 
      // [“00”],17
}

// String.replace(regex, replacement): 
console.log(inStr.replace(/\d+/, "**"));   // abc**xyz456_7_00 
console.log(inStr.replace(/\d+/g, "**"));  // abc**xyz**_**_**
</脚本>
</>
<正文>
  <h1>你好,</h1>
</正文>
</html>

1.4 示例:完整数字字符串^ [0-9]+ $ 或^\d+$

  1. 前导^和尾随$称为位置锚,它们分别匹配行的起始位置和结束位置。结果,整个输入字符串应完全匹配,而不是输入字符串的一部分(子字符串)。
  2. 此正则表达式匹配任何非空数字字符串(包含数字 0 到 9),例如“ 0”和“ 12345”。它不匹配“”(空字符串)、“ abc”、“a123”、“ abc123xyz”等。但是,它也匹配带前导零的“ 000”、“ 0123”和“ ”。0001

1.5 示例:正整数文字[1-9][0-9]|0或[1-9]\d|0

  1. [1-9]匹配 1 到 9 之间的任意字符;[0-9]匹配零个或多个数字。是表示零次或多次出现的出现指示符。一起匹配任何不带前导零的数字。[1-9][0-9]*
  2. |代表 OR 运算符;用于包含 number 0。
  3. 该表达式匹配“ 0”和“ 123”;但不匹配“ 000”和“ 0123”(但见下文)。
  4. 可以[0-9]用元字符替换\d,但不能[1-9]。
  5. 在这个正则表达式中,我们没有使用位置锚点 ^和。$因此,它可以匹配输入字符串的任何部分。举些例子,
    • 如果输入字符串是“ abc123xyz”,则匹配子字符串"123"。
    • 如果输入字符串为"abcxyz",则不匹配任何内容。
    • 如果输入字符串为"abc123xyz456_0",则它匹配子字符串"123"、“456"和"0”(三个匹配)。
    • 如果输入字符串是"0012300",则它匹配子字符串:“0”、“0"和"12300”(三个匹配)!!!

1.6 示例:全整数文字^ [±]?[1-9][0-9]|0$或^ [±]?[1-9]\d|0 $

  1. 此正则表达式匹配整数文字(对于具有位置锚的整个字符串),包括正数、负数和零。
  2. [±]匹配+或-符号。?是出现指示符,表示出现0次或1次,即可选的。因此,[±]?匹配可选的前导+或-符号。
  3. 我们已经介绍了三个出现指标:+一个或多个、*零个或多个以及?零个或一个。

1.7 示例:标识符(或名称)[a-zA-Z_][0-9a-zA-Z_]*或[a-zA-Z_]\w *

  1. 以一个字母或下划线开头,后跟零个或多个数字、字母和下划线。
  2. 您可以使用元字符 \w作为单词字符[a-zA-Z0-9_]。回想一下,元字符 \d可用于数字[0-9]。

1.8 示例:图像文件名^\w+.(gif|png|jpg|jpeg)$

  • 位置分别锚定 ^并 $匹配输入字符串的开头和结尾。也就是说,该正则表达式应匹配整个输入字符串,而不是输入字符串的一部分(子字符串)。
  • \w+匹配一个或多个单词字符(与 相同[a-zA-Z0-9_]+)。
  • .匹配点字符(.)。我们需要使用as在正则.表达式中具有特殊含义。这被称为转义码,它恢复后面字符的原始字面含义。同样,, ,(出现指示符), , (位置锚)在正则表达式中具有特殊含义。您需要使用转义码来匹配这些字符。…*+?^$
  • (gif|png|jpg|jpeg)匹配“ gif”、“ png”、“ jpg”或“
  • jpeg”。表示|“OR”运算符。括号用于对选择进行分组。 正则表达式后面的修饰符指定不区分大小写的匹配(仅适用于某些语言,例如 Perl和 JavaScript )。 i即,它接受“ test.GIF”和“ TesT.Gif”。

1.9 示例:电子邮件地址^\w+([.-]?\w+)@\w+([.-]?\w+)(.\w{2,3})+$

  1. 位置分别锚定 ^并$匹配输入字符串的开头和结尾。也就是说,该正则表达式应匹配整个输入字符串,而不是输入字符串的一部分(子字符串)。
  2. \w+匹配 1 个或多个单词字符(与 相同[a-zA-Z0-9_]+)。
  3. [.-]?匹配可选字符.或-. 尽管点 ( .) 在正则表达式中具有特殊含义,但在字符类(方括号)中,除^、-、]或之外的任何字符\都是文字,并且不需要转义序列。
  4. ([.-]?\w+)*匹配 0 次或多次出现[.-]?\w+。
  5. 子表达式\w+([.-]?\w+)*用于匹配电子邮件中符号之前的用户名@。它以至少一个单词字符开头[a-zA-Z0-9_],后跟更多单词字符 或.或-。但是,.or 后面-必须跟有单词字符[a-zA-Z0-9_]。即输入字符串不能以.or开头-;并且不能包含“ …”、“ --”、“ .-”或“ -.”。有效字符串的示例是“ a.1-2-3”。
  6. 比赛@本身。在正则表达式中,除了具有特殊含义的字符之外的所有字符都与自身匹配,例如amatches a、bmatchesb等。
  7. 同样,子表达式\w+([.-]?\w+)*用于匹配电子邮件域名,其模式与上述用户名相同。
  8. 子表达式.\w{2,3}匹配.后跟两个或三个单词字符,例如“ .com”、“ .edu”、“ .us”、“ .uk”、“ .co”。
  9. (.\w{2,3})+指定上述子表达式可以出现一次或多次,例如“ .com”、“ .co.uk”、“ .edu.sg”等。

1.10 示例:使用带括号的反向引用^(\S+)\s+(\S+)$和$2 $1交换单词

  1. 和^分别$匹配输入字符串的开头和结尾。
  2. \s(小写)s匹配空白(空白、制表符\t和换行符\r或\n)。另一方面,\S+(大写S) 匹配与 不匹配的任何内容\s,即非空白。在正则表达式中,大写元字符表示小写元字符的反义词,例如,\w对于单词字符和\W非单词字符;\d对于数字和\D/或非数字。
  3. 上述正则表达式匹配由一个或多个空格分隔的两个单词(没有空格)。
  4. 正则表达式中的括号()有两种含义:
    • 对子表达式进行分组,例如(abc)*
    • 为捕获和提取匹配项提供所谓的反向引用。
  5. 括号(\S+)称为括号反向引用,用于从输入字符串中提取匹配的子字符串。在此正则表达式中,有两个(\S+), 匹配前两个单词,并用一个或多个空格分隔\s+。两个匹配的单词是从输入字符串中提取的,通常分别保存在特殊变量$1and $2(或Python 中的\1and \2)中。
  6. 要交换两个单词,您可以访问特殊变量,并打印“ $2 $1”(通过编程语言);或替换运算符“ s/(\S+)\s+(\S+)/$2 $1/”(在 Perl 中)。

1.11 示例:HTTP 地址^http://\S+(/\S+)*(/)?$

  • 首先http://。请注意,您可能需要在某些语言(JavaScript、Perl)中编写/转义/码。
  • 后面跟着\S+一个或多个非空格,表示域名。
  • 后面跟着(/\S+)*零个或多个“/…”,表示子目录。
  • 后跟(/)?,一个可选的(0 或 1)尾随/,用于目录请求。

1.12 示例:AngularJS 中的正则表达式模式

AngularJS 在 JavaScript 语法中使用以下相当复杂的正则表达式模式:

var ISO_DATE_REGEXP = /^\d{4,}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\. \d+(?:[+-][0-2]\d:[0-5]\d|Z)$/;

var URL_REGEXP = /^[az][az\d.+-]*:\/*(?:[^:@]+(?::[^@]+)?@)?(?:[^\ s:/?#]+|\[[af\d:]+])(?::\d+)?(?:\/[^?#]*)?(?:\?[^#]* )?(?:#.*)?$/i;

var EMAIL_REGEXP = /^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?AZ^_`az{|}~ ]+(\.[-!#$%&'*+/0-9=?AZ^_`az{|}~]+)*@[A-Za-z0-9]([A-Za- z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[ A-Za-z0-9])?)*$/;
// 匹配大小写字母,单引号但不双引号

var NUMBER_REGEXP = /^\s*(-|\+)?(\d+|(\d*(\.\d*)))([eE][+-]?\d+)?\s*$/ ;

var DATE_REGEXP = /^(\d{4,})-(\d{2})-(\d{2})$/;

var DATETIMELOCAL_REGEXP = /^(\d{4,})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d) )(\.\d{1,3})?)?$/;

var WEEK_REGEXP = /^(\d{4,})-W(\d\d)$/;

var MONTH_REGEXP = /^(\d{4,})-(\d\d)$/;

var TIME_REGEXP = /^(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/;

1.13 示例:Perl 中的正则表达式示例

s/^\s+//         # 删除前导空格(用空字符串替换) 
s/\s+$//         # 删除尾随空格
s/^\s+.*\s+$//   # 删除前导和尾随空格
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

骑着骆驼去南极

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值