当前位置: 首页 > news >正文

常用的正则表达式

正则表达式中的分组(Groups in regexps)

首先,我们来介绍一个重要的概念:分组,这是我们在编写复杂正则表达式时需要用到的。分组的作用与数学表达式中的括号类似:它可以帮助我们设置操作的优先级

正则表达式的一部分可以用小括号括起来形成一个分组。我们也可以对每个分组应用量词(quantifier):如果你在括号后加上量词,它会应用于整个括号内的内容,而不是单个字符。

例如,下面的代码会查找文本中一对 “ho” 字符串的重复(一次或多次):

Java 示例
Pattern regexWithGroups = Pattern.compile("(ho)+");
String text = "ho hoho hohoho";Matcher resultWithGroups = regexWithGroups.matcher(text);
while (resultWithGroups.find()) {System.out.println(resultWithGroups.group());
}
Kotlin 示例
val regexWithGroups = """(ho)+""".toRegex()
val text = "ho hoho hohoho"val resultWithGroups = regexWithGroups.findAll(text)
for (res in resultWithGroups) println(res.value)

输出结果:

ho
hoho
hohoho

日期(Dates)

让我们从一个简单且常见的任务开始。假设你需要找出以下两种格式的日期:yyyy-mm-ddyyyy/mm/dd。怎么做?

我们需要匹配如下格式的文本:4 个数字,然后是一个可能的分隔符(/-),接着是 2 个数字相同的分隔符,再加 2 个数字。下面是实现这个目标的正则表达式:

\d{4}(-|\/)\d{2}\1\d{2}

解释:

  • \d{4}(-|\/):匹配 4 位数字,接着匹配一个分隔符(-/),并把它作为第一个分组

  • \d{2}\1:接下来匹配 2 位数字,后跟 第一个分组中提取的相同分隔符\1 表示第一个分组)。

  • 最后是 \d{2}:再匹配两个数字。

Java 示例
Pattern regex = Pattern.compile("\\d{4}(-|/)\\d{2}\\1\\d{2}");
String text = "Date 1: 2022-06-06" + "Date 2: 2021/01/01; date 3: 2020-02-02";Matcher dates = regex.matcher(text);
while (dates.find()) {System.out.println(dates.group());
}
Kotlin 示例
val regex = Regex("""\d{4}(-|\/)\d{2}\1\d{2}""")
val dates = regex.findAll("Date 1: 2022-06-06" +"Date 2: 2021/01/01; date 3: 2020-02-02")for (date in dates) println(date.value)

输出结果:

2022-06-06
2021/01/01
2020-02-02

注意:这个正则表达式虽然有效,但在现实场景中可能不够健壮,它仅覆盖了少数几种格式。


电话号码(Phone numbers)

之前我们简单介绍过电话号的正则写法。现在我们来写一个稍微复杂一些的正则。

我们假设电话号码有如下格式之一:

  • XXX-XXX-XXXX

  • (XXX)-XXX-XXXX

  • (XXX)XXXXXXX

  • XXXXXXXXXX

以下是相应的正则表达式:

\(?[\d]{3}\)?-?[\d]{3}-?[\d]{4}

解释:

  • \(?[\d]{3}\)?-?:匹配前 3 个数字,可能有括号包裹,也可能有连字符。

  • [\d]{3}-?:匹配中间 3 位数字和可选的连字符。

  • [\d]{4}:匹配最后 4 位数字。

Java 示例
Pattern regex = Pattern.compile("\\(?\\d{3}\\)?-?\\d{3}-?\\d{4}");
String text = "Ann's phone: 123-345-6789 " +"Dave's phone: (111)-234-5678, and next phone is (101)-234-5000";Matcher phones = regex.matcher(text);
while (phones.find()) {System.out.println(phones.group());
}
Kotlin 示例
val regex = Regex("""\(?[\d]{3}\)?-?[\d]{3}-?[\d]{4}""")
val phones = regex.findAll("Ann's phone: 123-345-6789 " +"Dave's phone: (111)-234-5678, and next phone is (101)-234-5000")for (phone in phones) println(phone.value)

输出结果:

123-345-6789
(111)-234-5678
(101)-234-5000

邮箱(Email)

假设你需要找出文本中的所有邮箱地址。标准邮箱格式是 "用户名@子域.主域"。下面的正则表达式可以匹配大多数常规邮箱:

([a-z0-9_\.-]+)@([a-z0-9_\.-]+)\.([a-z\.]{2,6})

解释:

  • 第 1 组:([a-z0-9_\.-]+) 匹配用户名,可以包含小写字母、数字、下划线、点和连字符。

  • 然后是 @ 符号。

  • 第 2 组:([a-z0-9_\.-]+) 匹配域名,同样可以包含这些字符。

  • 然后是 .

  • 第 3 组:([a-z\.]{2,6}) 匹配顶级域名(2-6 个小写字母或点)。

Java 示例
String patternStr = "([a-z0-9_\\.-]+)@([a-z0-9_\\.-]+)\\.([a-z\\.]{2,6})";
Pattern regex = Pattern.compile(patternStr);
String text = "We have the following emails: abc@mail.com, joe_blow@address.ing";Matcher matchResult = regex.matcher(text);
while (matchResult.find()) {System.out.println(matchResult.group());
}
Kotlin 示例
val regex = Regex("""([a-z0-9_\.-]+)@([a-z0-9_\.-]+)\.([a-z\.]{2,6})""")
val matchResult = regex.findAll("We have the following emails: " +"abc@mail.com, joe_blow@address.ing")for (matches in matchResult) println(matches.value)

输出结果:

abc@mail.com
joe_blow@address.ing

URL(网址)

手动从文本中提取链接非常繁琐,但使用正则表达式就轻松多了!

URL 示例:https://www.somesite.com/index.html

以下正则可以匹配大多数 URL:

(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w\.-]*)*\/?

解释:

  • 第 1 组:(https?:\/\/)? 匹配 http://https://,是可选的。

  • 第 2 组 + 第 3 组:([\da-z\.-]+)\.([a-z\.]{2,6}) 匹配主机名和顶级域名。

  • 第 4 组:([\/\w\.-]*)*\/? 匹配路径部分(字母、数字、点、斜杠等)。

Java 示例
String patternStr = "(https?:\\/\\/)?([\\da-z\\.-]+)\\.([a-z\\.]{2,6})([\\/\\w\\.-]*)*\\/?";
Pattern regex = Pattern.compile(patternStr);
String text = "Jet Brains Website: https://www.jetbrains.com/ " +"And here is information about Hyperskill: https://hi.hyperskill.org/how-we-teach";Matcher matchResult = regex.matcher(text);
while (matchResult.find()) {System.out.println(matchResult.group());
}
Kotlin 示例
val regex = Regex("""(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w\.-]*)*\/?""")
val matchResult = regex.findAll("Jet Brains Website: https://www.jetbrains.com/ " +"And here is information about Hyperskill: https://hi.hyperskill.org/how-we-teach")for (matches in matchResult) println(matches.value)

输出结果:

https://www.jetbrains.com/
https://hi.hyperskill.org/how-we-teach

http://www.lryc.cn/news/597124.html

相关文章:

  • 代码随想录算法训练营第五十二天|图论part3
  • 图论的题目整合(Dijkstra)
  • 【图论,拓扑排序】P1347 排序
  • 算法竞赛备赛——【图论】最小生成树
  • Modbus协议详解与c#应用
  • 算法竞赛备赛——【图论】拓扑排序
  • CI/CD与DevOps集成方法
  • python在windows电脑找回WiFi密码
  • 【按下电源键后,电脑里发生了什么?——BIOS:启动世界的“第一把钥匙”】
  • C++编程学习(第14天)
  • [Mediatek] MTK openwrt-21.02 wifi 没启动问题
  • 详述消息队列kafka
  • 【通识】手机和芯片相关
  • LazyVim 加载顺序
  • MySQL金融级数据一致性保障:从原理到实战
  • 数据持久化--PlayerPrefs
  • Hexo - 免费搭建个人博客06 - 安装、切换主题Butterfly
  • 基于Java实现DFT、FFT,并绘制波形图和频谱图,音频播放频谱或波形图
  • 内积(Inner Product)和余弦相似度区别
  • MATLAB近红外光谱分析:MATLAB编程+BP神经网络+SVM+随机森林+遗传算法+变量降维+卷积神经网络等
  • 以 “有机” 重构增长:云集从电商平台到健康生活社区的跃迁
  • 零工合规挑战:盖雅以智能安全体系重构企业用工风控
  • 认识linux进程内存布局以及与命令行参数和环境变量的关系
  • 如何在VS code里使用SQLtool连接上WSL上的MySQL服务
  • 【软件系统架构】系列七:物联网云平台系统性能深入解析
  • 线性神经网络(深度学习-李沐-学习笔记)
  • 探索大语言模型(LLM):提升 RAG 性能的全方位优化策略
  • 我考PostgreSQL中级专家证书二三事
  • 论文略读:REMEDY: RECIPE MERGING DYNAMICS IN LARGE VISION-LANGUAGE MODELS
  • vue3笔记(2)自用