深入剖析:正则表达式的奥秘-CSDN博客
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
简介
正则表达式Regular Expressions是一种强大的文本处理工具一种用于匹配文本模式的字符串。它由特定的字符和操作符组成用于定义一个搜索模式。这些搜索模式可以用于文本搜索、替换、验证和提取数据等多种用途。
以下是一个简单的示例
在写用户注册表单时用户名只允许包含字符、数字、下划线_和连接字符 -并设置用户名的长度为3~15个字符这时候就可以使用以下正则表达式/^[a-z0-9_-]{3,15}$/ 来设定。
因此这个正则表达式匹配的字符串必须满足以下条件
- 字符串长度在 3 到 15 个字符之间。
- 字符串中只能包含小写字母、数字和下划线和连字符。
这种正则表达式通常用于验证用户名、标识符或其他需要满足特定格式的字符串。如果输入的字符串符合上述规则正则表达式将匹配成功否则匹配将失败。
优点
使用正则表达式有许多优点这解释了为什么它们在各种编程和文本处理领域如此受欢迎。以下是一些主要的优点
- 强大的文本模式匹配 正则表达式允许你定义非常复杂的文本模式从简单的字符匹配到更复杂的模式如日期、电子邮件地址、电话号码等。
- 灵活性 正则表达式非常灵活可以应对多种文本处理需求。您可以轻松地自定义匹配模式以满足特定的要求。
- 广泛的应用领域 正则表达式可以应用于各种领域包括文本搜索、数据验证、日志分析、数据提取、编程语言中的模式匹配等。
- 快速和高效 正则表达式引擎经过高度优化可以快速执行匹配操作这使它们成为处理大量文本数据的理想工具。
- 一次性批处理 正则表达式可以同时处理多个匹配而无需迭代从而节省了时间和资源。
- 文本替代 正则表达式不仅可以用于匹配还可以用于替代文本。这使得在文本中进行搜索和替换操作非常容易。
- 标准化 正则表达式是一种标准化的文本匹配工具因此在不同编程语言和工具中的语法基本相同使得知识可迁移性很强。
- 表达力强 正则表达式支持逻辑运算、分组、捕获等高级功能允许构建复杂的匹配模式。
- 数据清洗 正则表达式可以用于清洗和转换数据将其从一个格式转换为另一个格式。
- 自然语言处理 在自然语言处理NLP任务中正则表达式可用于文本分析、分词和模式匹配从而帮助处理文本数据。
应用领域
正则表达式可以应用于许多领域和各种编程语言。以下是一些常见的应用领域
- 文本搜索和替换 正则表达式用于在文本中搜索和替换特定模式的字符串。这在文本编辑器、代码编辑器和命令行工具中非常常见。
- 数据验证 正则表达式可用于验证用户输入的数据是否符合特定格式如电子邮件地址、电话号码、日期、密码等。
- 日志分析 系统管理员和开发人员可以使用正则表达式来分析大型日志文件以查找特定事件、错误或信息。
- 数据提取 在文本数据中提取信息是正则表达式的常见用途。这可以用于从文本中提取网址、价格、标签、电话号码等。
- 编程语言中的模式匹配 编程语言如Python、Java和JavaScript允许使用正则表达式进行模式匹配和操作。这在字符串处理和文本解析中非常有用。
- 网页抓取和爬虫 网络爬虫可以使用正则表达式来定位和提取网页上的数据如链接、标题、日期等。
- 数据清洗 在数据分析中正则表达式可用于清理和转换数据以使其更易于分析。
- 路由和URL匹配 Web框架和路由系统使用正则表达式来匹配URL以确定哪个控制器或页面应该处理请求。
- 密码策略 正则表达式可用于定义密码策略要求密码满足特定的复杂性和长度要求。
- 自然语言处理 在自然语言处理NLP中正则表达式可以用于文本分析、分词和情感分析等任务。
- 数据替换和格式化 正则表达式可用于将数据转换为特定格式如日期格式化、数字格式化等。
- 日程表处理 正则表达式可以用于解析和处理日期、时间和日程表数据。
- 网络安全 正则表达式可用于检测恶意软件、网络入侵和安全威胁。
不同命令或环境下对正则表达式的支持
命令或环境 | . | [ ] | ^ | $ | \( \) | \{ \} | ? | + | | | ( ) |
vi | √ | √ | √ | √ | √ | |||||
Visual C++ | √ | √ | √ | √ | √ | |||||
awk | √ | √ | √ | √ | √ | √ | √ | √ | √ | |
sed | √ | √ | √ | √ | √ | √ | ||||
delphi | √ | √ | √ | √ | √ | √ | √ | √ | √ | |
python | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ |
java | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ |
javascript | √ | √ | √ | √ | √ | √ | √ | √ | √ | |
php | √ | √ | √ | √ | √ | |||||
perl | √ | √ | √ | √ | √ | √ | √ | √ | √ | |
C# | √ | √ | √ | √ | √ | √ | √ |
匹配规则
正则表达式的匹配规则基于特殊字符和模式构建这些字符和模式指定了要匹配的文本模式。
基本的模式匹配
模式指的是正则表达式中定义的文本模式是正则表达式最基本的元素用于搜索、匹配和操作文本。这个模式是由特殊字符、元字符和普通字符组成的它规定了你希望在文本中找到的具体模式。例如
/^once/
这个模式包含一个特殊字符 ^表示该模式只匹配以 once 开头的字符串。例如该模式与字符串 "once upon a time" 匹配与 "There once was a man from NewYork" 不匹配。
正如如 ^ 符号表示开头一样$ 符号用来匹配那些以给定模式结尾的字符串。
/bucket$/
这个模式与 "Who kept all of this cash in a bucket" 匹配与 "buckets" 不匹配。字符 ^ 和 $ 同时使用时表示精确匹配字符串与模式一样。例如
/^bucket$/
只匹配字符串 "bucket"。如果一个模式不包括 ^ 和 $那么它与任何包含该模式的字符串匹配。
例如模式/once/与字符串 “ There once was a man from NewYork Who kept all of his cash in a bucket. ” 是匹配的。该模式中的字母是字面的字符表示该字母本身。数字也是一样的。
其他一些稍微复杂的字符如标点符号和白字符空格、制表符等要用到转义序列。所有的转义序列都用反斜杠 \ 打头。制表符的转义序列是 \t。如果要检测一个字符串是否以制表符开头可以用模式^\t 。
类似的用 \n 表示"新行"\r 表示回车。其他的特殊符号可以用在前面加上反斜杠如反斜杠本身用 \\ 表示句号 . 用 \. 表示以此类推。
字符类
有时用正则表达式来验证用户的输入。当用户提交一个输入以后要判断输入的电话号码、地址、EMAIL 地址、信用卡号码等是否有效用普通的基于字面的字符是不够的。所以要用一种更自由的描述我们要的模式的办法它就是字符类。
例如要建立一个表示所有元音字符的字符类就把所有的元音字符放在一个方括号里
[AaEeIiOoUu]
注意这个模式与任何元音字符匹配但只能表示一个字符。
用连字号可以表示一个字符的范围同样也只表示一个字符。如
- [a-z] // 匹配所有的小写字母
- [a-zA-Z] // 匹配所有的字母
- [0-9\.\-] // 匹配所有的数字句号和连字符
注在正则表达式中小数点.和连字符-具有特殊含义它们通常用作元字符表示匹配任何字符小数点或指定字符范围连字符。如果你想要匹配这些字符的字面意义而不是使用它们的特殊含义需要对它们进行转义即在它们前面加上反斜杠\。
如果要匹配一个由一个小写字母和一位数字组成的字符串比如 "z2"、"t6" 用这个模式
/^[a-z][0-9]$/
尽管 [a-z] 代表 26 个字母的范围但在这里它只能与第一个是小写字母的字符串匹配。
^ 表示字符串的开头但当它在一组方括号里使用 ^ 时就表示"非"或"排除"的意思常常用来剔除某个字符。还用前面的例子现在要求第一个字符不能是数字而第二个字符是数字比如 "&5"、"g7"
/^[^0-9][0-9]$/
匹配的次数
目前为止你已经知道如何去匹配一个字母或数字但通常情况下需要匹配一个或多个字符或数字可以使用跟在字符或字符类后面的花括号 {N} 来确定前面的内容的重复匹配的次数。例如
a{3} | 精确匹配字符 "a" 重复出现 3 次。它只匹配 "aaa"不匹配其他重复次数的 "a"。 |
a{3,} | 匹配字符 "a" 重复出现的次数至少为 3 次或更多。这意味着它将匹配 "aaa"、"aaaa"、 "aaaaa" 等任何 "a" 重复次数大于或等于 3 次的情况。 |
a{1,3} | 匹配字符 "a" 重复出现的次数在 1 到 3 次之间。这意味着它将匹配 "a"、"aa" 或 "aaa" 但不会匹配没有 "a" 或重复次数超过 3 次的情况。 |
这些例子描述了花括号的三种不同的用法
- {N}匹配字符或字符类恰好 N 次
- {N,}匹配字符或字符类重复出现的次数至少为 N 次或更多
- {N,M}匹配字符或字符类重复出现的次数在 N 到 M 次之间。
可以把模式扩展到更多的单词或数字
- ^[a-zA-Z0-9_]{1,}$匹配所有包含一个以上的字母、数字或下划线的字符串
- ^[1-9][0-9]{0,}$匹配所有的正整数
当然这并不能从技术上降低正则表达式的复杂性但可以使它们更容易阅读。
正则表达式的模式
正则表达式是由字面值字符例如字符 a 到 z以及特殊字符称为"元字符"组成适当的文字模式用于定义要匹配的模式复杂程度取决于匹配模式的复杂性。模式描述的是在搜索文本时要匹配的一个或多个字符串。
字面值字符
正则表达式模式中的字面值字符即普通字符是指那些不具备特殊含义、没有显式指定为元字符的所有可打印和不可打印字符它们会与输入的文本字符进行精确匹配。字面值字符通常是正则表达式模式的基本构建块用于匹配特定字符或字符序列。以下是一些常见的字面值字符
- 字母和数字 字母和数字字符通常会与自身匹配。例如正则表达式中的字符 "a" 将精确匹配文本中的 "a"。
- 空格 空格字符通常用于匹配文本中的空格。
- 标点符号 大多数标点符号如句号、逗号、感叹号等也是字面值字符它们与输入文本中的相应字符进行匹配。例如字符 "." 将精确匹配文本中的句号。
- 特殊字符的转义 一些特殊字符如 $、(、)、[、]、.、*、+、? 等在正则表达式中具有特殊含义。如果您想匹配这些字符本身需要在它们前面加上反斜杠 \ 进行转义。例如要匹配文本中的 $ 字符可以使用 \ 进行转义写成 \$。
- 非打印字符的转义序列 非打印字符是一组特殊字符通常不可见如换行、回车、制表符等。这些字符在文本中存在但通常不会以字面形式可见而是用特殊的转义序列表示。
以下是一些非打印字符的示例以及它们在正则表达式和其他文本处理上下文中的转义序列
- 换行字符\n在正则表达式中\n 用于匹配文本中的换行字符。例如"Hello\nWorld" 匹配包含换行的字符串。
- 回车字符\r用于匹配回车字符。例如"Line1\rLine2" 匹配包含回车的字符串。
- 制表符\t用于匹配制表符。例如"Value1\tValue2" 匹配包含制表符的字符串。
- 垂直制表符\v用于匹配垂直制表符。例如"Item1\vItem2" 匹配包含垂直制表符的字符串。
- 换页字符\f用于匹配换页字符。例如"Page1\fPage2" 匹配包含换页字符的字符串。
这些转义序列允许你在正则表达式和其他文本处理上下文中匹配、替换或操作非打印字符尽管这些字符通常是不可见的。
- Unicode字符正则表达式也支持匹配特定的Unicode字符例如\uXXXX 可以用于匹配Unicode编码为XXXX的字符。
特殊字符元字符
正则表达式中的特殊字符是那些具有特殊含义的字符它们不会与输入文本中的相同字符进行精确匹配而是用于构建匹配模式或执行特定的匹配操作。
许多元字符要求在试图匹配它们时特别对待。若要匹配这些特殊字符必须首先使字符"转义"即将反斜杠字符\ 放在它们前面。如 abc*b 中的 *表示任何字符串。如果要查找字符串中的 * 符号则需要对 * 进行转义即abc\*b 。
基本字符匹配
- \转义字符用于匹配特殊字符本身或标记为一个原义字符、或一个向后引用、或一个八进制转义符。例如'n' 匹配字符 "n"。'\n' 匹配一个换行符。序列 '\\' 匹配 "\" 而 "\(" 则匹配 "("。
- .匹配除换行符之外的任何字符。但在字符类 [.] 中只会匹配字符 .
- |用于创建分支结构匹配多个模式中的一个。例如'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。
- \s表示匹配空白字符Whitespace Character包括空格、制表符、换行符和其他空白字符。
- \S匹配任何非空白字符。不包括换行。
- \w表示匹配单词字符Word Character通常包括字母、数字和下划线。
- \W匹配非单词字符Non-Word Character等效于 [^A-Za-z0-9_]。用于匹配非单词字符。
- \d匹配数字字符Digit Character等效于 [0-9]。用于匹配数字。
- \D匹配非数字字符Non-Digit Character等效于 [^0-9]。用于匹配非数字字符。
- \b匹配单词边界Word Boundary。用于在单词边界位置匹配不匹配字符本身。
- \B匹配非单词边界Non-Word Boundary。用于在非单词边界位置匹配不匹配字符本身。
- \f匹配换页字符Form Feed通常用于在文本中进行页面分隔。
- \n匹配换行字符Line Feed通常表示文本中的行结束。
- \r匹配回车字符Carriage Return通常表示文本中的行的起始或行结束。
- \t匹配制表符Tab用于表示文本中的制表符。
- \v匹配垂直制表符Vertical Tab通常用于在文本中进行垂直对齐。
限定符量词
限定符通常也被称为量词用于整个范围表达式之后。用来指定正则表达式的前一个元素字符、字符类、子表达式等的匹配次数以控制匹配的数量。{ 和 } 标记范围表达式的开始和结束位置。
- *匹配前面的模式子表达式零次或多次。
- +匹配前面的模式一次或多次。
- ?匹配前面的模式零次或一次例如do(es)? 可以匹配 "do" 、 "does"、或 "doxy" 中的 "do" ? 等价于 {0,1}。
- ?紧跟在其他限制符后面时指明匹配模式为非贪婪。非贪婪模式尽可能少的匹配所搜索的字符串而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如'o+?' 将匹配字符串 "oooo" 的单个 "o"而 'o+' 将匹配所有 'o'。
- {n}匹配前面的模式恰好 n 次n 是一个非负整数。例如o{2} 不能匹配 "Bob" 中的 o但是能匹配 "food" 中的两个 o。
- {n,}匹配前面的模式至少 n 次n 是一个非负整数。例如o{2,} 不能匹配 "Bob" 中的 o但能匹配 "foooood" 中的所有 o。o{1,} 等价于 o+。o{0,} 则等价于 o*。
- {n,m}匹配前面的模式至少 n 次且不超过 m 次m 和 n 均为非负整数其中 n <= m。例如o{1,3} 将匹配 "fooooood" 中的前三个 o。o{0,1} 等价于 o?。请注意在逗号和两个数之间不能有空格。
贪婪和非贪婪
在正则表达式中"贪婪"Greedy和"非贪婪"Non-Greedy是描述匹配模式的两种行为方式。它们影响匹配重复的模式时的行为尤其是在使用限定符例如 *、+、?、{n,}时。
- 贪婪匹配Greedy Matching默认情况下正则表达式是贪婪的。这意味着它会尽可能多地匹配字符以满足模式。例如对于正则表达式 a.*b 和字符串 "axxxbyyybz"贪婪匹配将匹配"axxxbyyyb"而不是只匹配 "axxxb"。
- 非贪婪匹配Non-Greedy Matching也称为懒惰匹配使用 ? 后缀来实现例如 *?、+?、??、{n,}?。这表示匹配将尽可能少地匹配字符以满足模式。例如对于正则表达式 a.*?b 和字符串 "axxxbyyybz"非贪婪匹配将只匹配 "axxxb"而不是整个字符串。
非贪婪匹配在某些情况下非常有用特别是当你需要匹配尽可能短的内容或在文本中找到最小的匹配项时。贪婪匹配通常用于匹配尽可能多的内容。
定位符边界匹配
定位符用于指定匹配发生的位置而不是匹配字符本身。定位符还允许你在文本中定义位置使正则表达式匹配在一个单词的内部、开头或结尾以便更精确地匹配所需的文本以满足特定的匹配需求而不一定匹配具体的字符。以下是一些常见的正则表达式定位符
- ^在模式的开头使用 ^表示匹配字符串的开头。例如^abc 匹配以 "abc" 开头的字符串。
- $在模式的末尾使用$表示匹配字符串的结尾。例如xyz$ 匹配以 "xyz" 结尾的字符串。
- \b匹配单词边界。单词边界通常是单词字符字母、数字、下划线和非单词字符之间的位置。例如\bword\b 匹配 "word" 作为一个单词的出现不匹配 "subword" 中的 "word"。
- \B匹配非单词边界。与 \b 相反\B 匹配不是单词边界的位置。例如\Bword\B 匹配 "subword" 中的 "word"但不匹配 "word" 作为一个单独的单词。
注意正则表达式中允许在紧靠换行或单词边界的前面或后面使用定位符如 ^行的开始、$行的结束以及 \b单词边界。这些定位符在正则表达式中是合法的并且常常用于匹配特定位置的文本。然而像 ^* 这样的表达式是无效的因为 ^ 是一个定位符用于匹配行的开始而 * 是一个限定符用于匹配前面的模式零次或多次。将它们组合在一起没有明确定义因此不是有效的正则表达式必须按照正则表达式的语法规则来组合和使用它们。
示例搜索章节标题。章节标题通常出现行的开始处又出现在同一行的结尾且是该行唯一存在的文本。下面的正则表达式能确保只匹配章节而不匹配交叉引用。使用定位点创建只匹配一行文本的开始和结尾的正则表达式就可做到这一点。
/^Chapter [1-9][0-9]{0,1}$/
示例匹配单词边界。单词边界是单词和空格之间的位置非单词边界是其他任何位置。下面的表达式匹配单词 Chapter 的开头三个字符因为这三个字符出现在单词边界后面
/\bCha/
\b 字符位置的不同表示不同的含义
位于字符串的开始它在单词的开始处查找匹配项
位于字符串的结尾它在单词的结尾处查找匹配项。
例如下面的表达式匹配单词 Chapter 中的字符串 ter因为它出现在单词边界的前面
/ter\b/
对于 \B 非单词边界运算符不可以匹配单词的开头或结尾下面的表达式匹配 Chapter 中的字符串 apt但不匹配 aptitude 中的字符串 apt
/\Bapt/
字符类
字符类是一组字符或字符范围用于指定匹配的字符集合使用 [ ] 来定义字符类。范围表达式是字符类中的一种方式使用连字符 - 指定一个范围内的字符而不必逐个列出每个字符。例如正则表达式 [a-z] 表示匹配小写英文字母 a 到 z 之间的任何一个字符。
- [ ]用于创建字符类匹配字符集合中的任何一个字符。
- [^ ]匹配除了括号内的字符以外的任意一个字符。例如[^abc] 匹配除了字符 "a"、"b" 或 "c" 以外的任意字符。
基本字符类
- [abc]匹配字符集合中的任何一个字符即匹配 "a"、"b" 或 "c"。
字符范围
- [0-9]匹配任何数字字符。
- [a-z]匹配任何小写字母。
- [A-Z]匹配任何大写字母。
- [a-zA-Z]匹配任何字母包括小写和大写。
- [a-zA-Z0-9]匹配任何英文字母或数字字符
字符类的否定
- [^abc]匹配除了 "a"、"b" 和 "c" 之外的任何字符。
- [^0-9]匹配非数字字符。
- [^A-Za-z]匹配非字母字符。
字符类中的特殊字符
- [.]匹配句号字符。
- [\^]匹配插入符字符。
- [-]匹配连字符字符。
分组
正则表达式中的分组是指使用括号 ( ) 将模式的一部分子表达式括起来分组在一起以便对其应用修饰符、重复次数或后续引用以便更灵活地控制匹配行为和提取匹配的子字符串。
以下是正则表达式分组的常见用途
捕获组
捕获组是最常见的分组类型。它们使用括号将子表达式括起来以便将匹配的文本保存到一个单独的组中以便稍后引用或进行后续处理。捕获组具有捕获功能可以捕获匹配的子字符串以备后续引用或处理。
每个捕获组都有一个编号通常从1开始。可以使用捕获组的编号来引用捕获的子字符串。例如
正则表达式(\d{3})-(\d{2})
匹配示例 "123-45"
捕获组Group 1 包含 "123"Group 2 包含 "45"
非捕获分组
非捕获组也使用括号但它们以 (?: ) 的形式表示。非捕获组用于分组子表达式但不会将匹配的文本保存到单独的组中从而提高正则表达式的性能。非捕获组通常用于模式分组而不需要后续引用或处理匹配。例如
正则表达式(?:\d{3})-(\d{2})
匹配示例 "123-45"
非捕获组不会创建额外的组仅捕获 "45"
后向引用
分组允许在正则表达式中引用先前捕获的文本。这对于替换文本或在模式中多次使用相同的子字符串非常有用。
在正则表达式模式中可以使用 \ 加捕获组编号来引用已捕获的子字符串以便在模式中再次使用它们。例如 \1、\2其中 \1 引用捕获组 1 中的内容\2 引用捕获组 2 中的内容以此类推。例如
正则表达式<(\w+)>.+<\/\1>
匹配示例 "<div>内容</div>"
后向引用\1 引用第一个捕获组即 (\w+) 匹配的标签名以确保开标签和闭标签匹配。
断言
断言是正则表达式中的一种特殊语法它用于在匹配模式中添加条件以约束匹配的文本。断言不会捕获实际的文本而是对文本的上下文进行约束以确保匹配满足特定的条件。
有两种主要类型的断言
正向断言Lookahead Assertion正向断言用于指定匹配必须满足的条件但不包括条件本身。常见的正向断言包括
- 正向先行断言 (?=...)表示匹配必须满足括号内的条件但不包括条件本身。示例匹配 "apple" 后面紧跟着 "pie" 的文本。
apple(?=pie)
- 正向后行断言 (?<=...)表示匹配必须前面是括号内的条件但不包括条件本身。示例匹配前面紧跟着 "good" 的单词 "job"。
(?<=good )job
负向断言Negative Lookahead Assertion负向断言用于指定匹配不能满足的条件。常见的负向断言包括
- 负向先行断言 (?!...)表示匹配不能满足括号内的条件。示例匹配后面不跟着文本 "pie" 的 "apple" 。
apple(?!pie)
- 负向后行断言 (?<!...)表示匹配不能前面是括号内的条件。示例匹配前面不是 "bad " 的单词 "apple"。
(?<!bad )apple
修饰符标记
正则表达式的修饰符也称为标志用于修改正则表达式的匹配行为的特殊标记通常以字母的形式出现在正则表达式的末尾并影响匹配的方式。
标记不写在正则表达式里标记位于表达式之外格式如下
/pattern/flags
以下是一些常见的正则表达式修饰符
- i不区分大小写当启用这个修饰符时正则表达式将不区分字母的大小写。例如/apple/i 匹配 "apple"、"Apple" 和 "aPpLe" 等。
- g全局匹配启用全局匹配后正则表达式将尝试找到所有匹配而不仅仅是第一个匹配。例如/abc/g 将匹配 "abc abc abc" 中的所有 "abc"。
- m多行匹配启用多行匹配后正则表达式中的 ^ 和 $ 将分别匹配行的开头和行的结尾而不仅仅是整个字符串的开头和结尾。例如/^abc/m 匹配 "abc def\nabc ghi" 两行的开头的 "abc"。
- s单行匹配启用单行匹配后点号 . 匹配任何字符包括换行符 \n。例如/a.b/s 可以匹配 "a\nb", "a b", "a\tb"。
- uUnicode匹配启用 Unicode 匹配后正则表达式将支持 Unicode 字符并允许匹配各种语言的字符。例如/\p{Sc}/u 可以匹配各种货币符号如 "$"、"€" 和 "₣"。
- y粘性匹配启用粘性匹配后匹配从字符串的当前位置开始而不是从头开始。例如在 "abc abc abc" 中匹配了第一个 "abc" 后/abc/y 将继续查找下一个 "abc"而不会重新从字符串的开头开始匹配。
这些修饰符可以单独使用也可以组合使用以根据需要修改正则表达式的匹配行为。修饰符在不同编程语言和正则表达式引擎中的语法可能会有所不同因此确保查阅特定语言或引擎的文档以了解如何正确使用它们。
运算符优先级
正则表达式中的运算符优先级指的是不同正则表达式元素的匹配顺序和结合性。了解正则表达式的运算符优先级很重要因为它们会影响匹配的行为。正则表达式从左到右进行计算以下是常见正则表达式运算符和元素的优先级按从高到低的顺序
- 转义符号\用于转义特殊字符如 \., \*。
- 圆括号( 和 )用于分组和捕获。
- 字符类和字符范围[ ]用于指定字符集。
- 量词*, +, ?, {n}, {n,}, {n,m}用于指定匹配次数。
- 定位符^, $用于匹配字符串的开始和结束。
- 逻辑或|用于在多个模式之间选择一个。
- 断言(?=...), (?!...), (?<=...), (?<!...)用于条件测试。
这个优先级顺序是默认情况下的但你可以使用括号来显式指定运算的顺序以满足特定匹配需求。括号可以用于分组操作从而改变运算符的结合性。
实例
实例1查找文本中重复的单词
以此句为例
This Is is the Top-Rated Tourist Attraction in in the U.S.—and It’s Completely Free free!
下面的正则表达式使用单个子表达式来实现这一点
/\b([a-z]+) \1\b/igm
正则表达式 /\b([a-z]+) \1\b/igm 的目的是匹配连续重复的单词。它的各部分含义如下
- \b匹配单词边界确保匹配的单词是整个单词而不是其它单词的一部分诸如 "is issue" 或 "This is" 之类。
- ([a-z]+)这是一个捕获组用于匹配一个或多个小写字母字符。
- 空格字符 " "匹配一个空格相邻单词间的空格。
- \1这是后向引用引用前面捕获的内容即([a-z]+)捕获的内容。
正则表达式模式中的 i、g 和 m 是修饰符标记它们表示以下内容
- i不区分大小写允许匹配小写和大写字母。
- g全局匹配匹配所有符合条件的模式而不仅仅是第一个。
- m多行匹配允许匹配跨行的文本。
对于输入字符串 "This Is is the Top-Rated Tourist Attraction in in the U.S.—and It’s Completely Free free!"它将匹配 "is is" 和 "in in" 和 “Free free”。
实例2将 URI 分解为其组件
URI 是通用资源标识符(Uniform Resource Identifier)的缩写用于标识互联网上资源的字符串包括但不限于网页、文件、数据库条目、电子邮件地址和其他资源。URI 的主要目的是唯一标识和定位资源以便浏览器、网络应用程序和其他工具可以访问这些资源。
将下面的 URI 分解为协议ftp、http 等等、域地址和页/路径
https://www.runoob.com:80/html/html-tutorial.html
下面的正则表达式提供该功能
/(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/
以下是每个捕获组在此 URL 中的匹配
- (\w+)匹配了 "https"这是URL的协议部分。
- :\/\/匹配了 "://"URL中的分隔符表示协议和主机之间的分隔。斜杠字符 / 是一个特殊字符通常用作正则表达式的开始和结束标记。因此匹配斜杠字符 / 本身需要对其进行转义即使用反斜杠 \ 来转义它写作 \/。
- ([^/:]+)匹配了 "www.runoob.com"这是主机名部分。它匹配主机名但不包括端口号。字符类 [^/:]+ 匹配一个或多个字符这些字符既不是冒号 : 也不是斜杠 /。字符类 [^...] 表示匹配除括号中列出的字符之外的任何字符。
- (:\d*)?匹配了 ":80"这是可选的端口号部分。这个部分包括冒号和数字字符表示端口号。在此示例中端口号为 80。
- ([^# ]*)匹配了 "/html/html-tutorial.html"这是路径部分表示资源的位置和文件名。这个部分匹配除井号 "#" 和空格之外的所有字符序列。
正则表达式成功地将 URL https://www.runoob.com:80/html/html-tutorial.html 分成了协议、主机、端口和路径组件以便后续处理和解析。