深入剖析:正则表达式的奥秘

news2024/11/27 4:18:47

简介

正则表达式(Regular Expressions)是一种强大的文本处理工具,一种用于匹配文本模式的字符串。它由特定的字符和操作符组成,用于定义一个搜索模式。这些搜索模式可以用于文本搜索、替换、验证和提取数据等多种用途。

以下是一个简单的示例: 

在写用户注册表单时,用户名只允许包含字符、数字、下划线_和连接字符 -,并设置用户名的长度为3~15个字符,这时候就可以使用以下正则表达式:/^[a-z0-9_-]{3,15}$/ 来设定。

因此,这个正则表达式匹配的字符串必须满足以下条件:

  1. 字符串长度在 3 到 15 个字符之间。
  2. 字符串中只能包含小写字母、数字和下划线和连字符。

这种正则表达式通常用于验证用户名、标识符或其他需要满足特定格式的字符串。如果输入的字符串符合上述规则,正则表达式将匹配成功;否则,匹配将失败。

优点

使用正则表达式有许多优点,这解释了为什么它们在各种编程和文本处理领域如此受欢迎。以下是一些主要的优点:

  • 强大的文本模式匹配: 正则表达式允许你定义非常复杂的文本模式,从简单的字符匹配到更复杂的模式,如日期、电子邮件地址、电话号码等。
  • 灵活性: 正则表达式非常灵活,可以应对多种文本处理需求。您可以轻松地自定义匹配模式,以满足特定的要求。
  • 广泛的应用领域: 正则表达式可以应用于各种领域,包括文本搜索、数据验证、日志分析、数据提取、编程语言中的模式匹配等。
  • 快速和高效: 正则表达式引擎经过高度优化,可以快速执行匹配操作,这使它们成为处理大量文本数据的理想工具。
  • 一次性批处理: 正则表达式可以同时处理多个匹配,而无需迭代,从而节省了时间和资源。
  • 文本替代: 正则表达式不仅可以用于匹配,还可以用于替代文本。这使得在文本中进行搜索和替换操作非常容易。
  • 标准化: 正则表达式是一种标准化的文本匹配工具,因此在不同编程语言和工具中的语法基本相同,使得知识可迁移性很强。
  • 表达力强: 正则表达式支持逻辑运算、分组、捕获等高级功能,允许构建复杂的匹配模式。
  • 数据清洗: 正则表达式可以用于清洗和转换数据,将其从一个格式转换为另一个格式。
  • 自然语言处理: 在自然语言处理(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"。
  • u(Unicode匹配):启用 Unicode 匹配后,正则表达式将支持 Unicode 字符,并允许匹配各种语言的字符。例如,/\p{Sc}/u 可以匹配各种货币符号,如 "$"、"€" 和 "₣"。
  • y(粘性匹配):启用粘性匹配后,匹配从字符串的当前位置开始,而不是从头开始。例如,在 "abc abc abc" 中,匹配了第一个 "abc" 后,/abc/y 将继续查找下一个 "abc",而不会重新从字符串的开头开始匹配。

这些修饰符可以单独使用,也可以组合使用,以根据需要修改正则表达式的匹配行为。修饰符在不同编程语言和正则表达式引擎中的语法可能会有所不同,因此确保查阅特定语言或引擎的文档以了解如何正确使用它们。


运算符优先级

正则表达式中的运算符优先级指的是不同正则表达式元素的匹配顺序和结合性。了解正则表达式的运算符优先级很重要,因为它们会影响匹配的行为。正则表达式从左到右进行计算,以下是常见正则表达式运算符和元素的优先级,按从高到低的顺序:

  1. 转义符号:\,用于转义特殊字符,如 \., \*。
  2. 圆括号:( 和 ),用于分组和捕获。
  3. 字符类和字符范围:[ ],用于指定字符集。
  4. 量词:*, +, ?, {n}, {n,}, {n,m},用于指定匹配次数。
  5. 定位符:^, $,用于匹配字符串的开始和结束。
  6. 逻辑或:|,用于在多个模式之间选择一个。
  7. 断言:(?=...), (?!...), (?<=...), (?<!...),用于条件测试。

这个优先级顺序是默认情况下的,但你可以使用括号来显式指定运算的顺序,以满足特定匹配需求。括号可以用于分组操作,从而改变运算符的结合性。


实例

实例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 分成了协议、主机、端口和路径组件,以便后续处理和解析。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1173071.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在搜索引擎中屏蔽csdn

csdn是一个很好的技术博客&#xff0c;里面信息很丰富&#xff0c;我也喜欢在csdn上做技术笔记。 但是CSDN体量太大&#xff0c;文章质量良莠不齐。当在搜索引擎搜索技术问题时&#xff0c;搜索结果中CSDN的内容占比太多&#xff0c;导致难以从其他优秀的博客平台中获取信息。因…

Mac安装VMware

去官网下载一下VMware Download VMware Fusion | VMware | SG 下载完成之后&#xff0c;打开直接闪退&#xff0c;参考这篇文章解决 解决macOS13安装Fusion13闪退的问题-CSDN博客 然后即可成功顺行

linux入门到地狱

linux—001入门 IT圈必备(前端工作者用的比较少) 老旧电脑跑linux不容易卡 我代码没保存windows闪退&#xff0c;僵停(vs2019卡掉线)&#xff0c;重启更新,占用cpu内存服务报错pip各种bug 出来生态环境友好其他的全是bug(bug时间成本超过了windows快捷友好生态) 那就说明wind…

行业安卓主板-基于RK3568/3288/3588的AI视觉秤/云相框/点餐机/明厨亮灶行业解决方案(一)

AI视觉秤 单屏Al秤集成独立NPU&#xff0c;可达0.8Tops算力&#xff0c;令AI运算效率大幅提升&#xff0c;以实现生鲜商品快速准确识别&#xff0c;快速称重打印标签&#xff0c;降低生鲜门店运营成本&#xff0c;缓解高峰期称重排队拥堵的现象&#xff0c;提高称重效率&#…

1、Sentinel基本应用限流规则(1)

Sentinel基本应用&限流规则 1.1 概述与作用 随着微服务的流行&#xff0c;服务和服务之间的稳定性变得越来越重要。缓存、降级和限流是保护微服务系统运行稳定性的三大利器。 缓存&#xff1a;提升系统访问速度和增大系统能处理的容量 降级&#xff1a;当服务出问题或者影…

如何写复盘报告

复盘报告在it公司中是为了在出现事情后&#xff0c;我们更好的回顾事情的前因后果&#xff0c;定位问题&#xff0c;指定解决措施&#xff0c;并且宣导&#xff0c;让这类事情减少发生的概率。那复盘报告一般怎样写合适呢&#xff1f;下来我们就看看&#xff0c; 一、一般会先…

Elasticsearch:RAG vs Fine-tunning (大语言模型微调)

如果你对 RAG 还不是很熟悉的话&#xff0c;请阅读之前的文章 “Elasticsearch&#xff1a;什么是检索增强生成 - RAG&#xff1f;”。你可以阅读文章 “Elasticsearch&#xff1a;在你的数据上训练大型语言模型 (LLM)” 来了解更多关于如何训练你的模型。在今天的文章中&#…

Linux项目自动化构建工具-make/Makefile使用

make/Makefile使用介绍 make是一个命令makefile是一个在当前目录下存在的一个具有特定格式的文本文件 ​ 下面我们设计一个场景&#xff0c;实现make命令对我们code.c文件进行编译和删除。 1 #include<stdio.h> 2 3 int main() 4 { 5 printf("hello,world!…

账户权限控制

1.首先配置一个单群组4节点的链 1.1创建操作目录 cd ~ && mkdir -p fisco && cd fisco 1.2下载国内脚本 curl -#LO https://osp-1257653870.cos.ap-guangzhou.myqcloud.com/FISCO-BCOS/FISCO-BCOS/releases/v2.9.1/build_chain.sh && chmod ux bu…

Python算法例7 四数乘积

1. 问题描述 给定一个长度为n的数组a和一个正整数k&#xff0c;从数组中选择四个数&#xff0c;要求四个数的乘积小于等于k&#xff0c;求方案总数。 2. 问题示例 给定n5&#xff0c;a[1&#xff0c;1&#xff0c;1&#xff0c;2&#xff0c;2]&#xff0c;k3&#xff0c;返…

R语言 复习 习题图片

这是日天土申哥不知道从哪淘来的R语言复习知识点图片&#xff0c;大部分内容都是课后习题的答案 加油吧&#xff0c;骚年&#xff0c;考个好分数

【重学C++基础知识笔记】详细版

基础 常量 C++ 中有两种简单的定义常量的方法: 使用#define,如:#define PI 3.1415926;使用const, 如:const double PI = 3.1415926;注明: 尽量使用const定义变量,#define不会出现在编译器期 #define ASPECT RATIO 1.653 // 在编译时出错,很难排错const doubl…

windows自动登陆

新建文本粘贴下面代码&#xff0c;另存为注册表文件 Windows Registry Editor Version 5.00[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Driver Signing] "Policy"hex:00[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon]"DefaultUserN…

04 矩阵乘法与线性变换复合

矩阵乘法与线性变换复合 复合变换 这是关于3Blue1Brown "线性代数的本质"的学习笔记。 复合变换 图1 复合变换 复合变换原则&#xff0c;依次变换&#xff0c;即先变换的矩阵乘待变换的向量后&#xff0c;得到的结果&#xff0c;再用后变换的矩阵乘此结果向量。从矩…

SPSS多因素方差分析

前言&#xff1a; 本专栏参考教材为《SPSS22.0从入门到精通》&#xff0c;由于软件版本原因&#xff0c;部分内容有所改变&#xff0c;为适应软件版本的变化&#xff0c;特此创作此专栏便于大家学习。本专栏使用软件为&#xff1a;SPSS25.0 本专栏所有的数据文件请点击此链接下…

CleanMyMac X2024登录激活码

本篇将为各位小伙伴们集中讲解一下&#xff0c;Mac清理工具CleanMyMac X的下载、安装与激活是如何进行的。 系统&#xff1a;macOS 10.14&#xff08;在10.15以及Big Sur中的安装激活教程相同&#xff09; 下载CleanMyMac X 登录CleanMyMac X下载页面&#xff0c;然后点击【…

3、Sentinel 动态限流规则

Sentinel 的理念是开发者只需要关注资源的定义&#xff0c;当资源定义成功后可以动态增加各种流控降级规则。Sentinel 提供两种方式修改规则&#xff1a; • 通过 API 直接修改 (loadRules) • 通过 DataSource 适配不同数据源修改 通过 API 修改比较直观&#xff0c;可以通…

sql基础+考点+题

查询&#xff1a;select from 筛选&#xff1a;where and和or 排序&#xff1a;order by&#xff08;降序排列需要指定DESC关键字&#xff09; join&#xff1a;left join 、right join 和inner join 分组聚合&#xff1a;group by ---搭配count , sum , avg 过滤&#x…

2023年中国自然语言处理行业研究报告

第一章 行业概况 1.1 定义 自然语言处理&#xff08;Natural Language Processing&#xff0c;简称NLP&#xff09;是一门交叉学科&#xff0c;它结合了计算机科学、人工智能和语言学的知识&#xff0c;旨在使计算机能够理解、解释和生成人类语言。NLP的核心是构建能够理解和…

Ubuntu 创建用户

在ubuntu系统中创建用户&#xff0c;是最基本的操作。与centos7相比&#xff0c;有较大不同。 我们通过案例介绍&#xff0c;讨论用户的创建。 我们知道&#xff0c;在linux中&#xff0c;有三类用户&#xff1a;超级管理员 root 具有完全权限&#xff1b;系统用户 bin sys a…