文章      动态     相关文章     最新文章     手机版动态     相关动态     |   首页|会员中心|保存桌面|手机浏览

v48pv4

http://keair.bhha.com.cn/comv48pv4/

元字符-选择匹配符

在匹配某个字符串的时候是选择性的,即:既可以匹配这个,又可以匹配那个,这时需要用到选择匹配符号

结果

元字符-限定符

用于指定其前面的字符和组合项连续出现多少次

注意:Java 匹配默认贪婪匹配,即尽可能匹配多的

元字符-定位符

定位符,规定要匹配的字符串出现的位置,比如在字符串的开始还是在结束的位置,这个也是相当有用的,必须掌握。

应用实例

手机号码

要求: 必须以 13,14,15,18 开头的 11 位数 , 比如 13588889999

url 地址

思路:

  1. 先确定 url 的开始部分 https:// | http:
  2. .然后通过 ([\w-]+.)+[\w-] 匹配

头的 11 位数 , 比如 13588889999

url 地址

思路:

  1. 先确定 url 的开始部分 https:// | http:
  2. .然后通过 ([\w-]+.)+[\w-] 匹配
相关列表
文章列表
  • 暂无文章
推荐文章
联系方式
  • 联系人:汪女士
  • 电话:15066621024
正则表达式手机号定位「正则表达式」
发布时间:2025-02-02        浏览次数:8        返回列表
  1. 提取文章中所有的英文单词
  2. 提取文章中所有的数字
  3. 提取文章中所有的英文单词和数字
  4. 给你一个字符串(或文章),请你找出所有四个数字连在一起的字串
  5. 请验证输入的邮件,是否符合电子邮件格式
  6. 请验证输入的手机号,是否符合手机号格式

结论:正则表达式是处理文本的利器

  1. 一个正则表达式,就是用某种模式去匹配字符串的一个公式。很多人因为正则表达式看上去比较古怪而且复杂所以不敢去使用。但是当你看完这篇文章并去加以练习后就会觉得这些复杂的表达式写起来还是相当简单的,而且,一旦你弄懂它们,你就能把数小时辛苦而且易错的文本处理工作缩短在几分钟(甚至几秒钟)内完成。

  2. 正则表达式:regular expression => RegExp

简单的说:正则表达式是对字符串执行模式匹配的技术。

1.提取文章中所有的英文单词

 

运行结果

 

代码解读

  1. 先创建一个 Pattern 对象 , 模式对象, 可以理解成就是一个正则表达式对象
 
  1. 创建一个匹配器对象

就是 matcher 匹配器按照 pattern (模式/样式), 到 content 文本中去匹配,找到就返回 true, 否则就返回 false

 
  1. 可以开始循环匹配
 

关于 matcher.find() 和 matcher.group() 涉及到源码,此处的源码挺简单,建议阅读

会了这一个例子之后,掌握了正则表达式的三个步骤,做其它的匹配都是大同小异的,下面再举几个例子来巩固一下。

2.提取文章中所有的数字

注意,其它的代码都和上面的代码完全一样,只是正则表达式变了而已

 

运行结果

 

3.提取文章中所有的英文单词和数字

 

运行结果

 

4.提取 IP 地址

 
 

\d 表示一个任意的数字

运行结果

 
 

主要就是研究 matcher.find() 和 matcher.group()

通过一个例子来说明,即找到字符串里的连续4个数字

强烈建议:自己进行 debug,在第 16 行的位置加一个断点。用文字来叙述的话是不太好描述的,建议大家看完之后,自己进行 debug

 

代码是如何找到 1998 的
matcher.find() 完成的任务:

  1. 根据指定的规则 ,定位满足规则的子字符串(比如 1998 )
  2. 找到后,将子字符串的开始的索引记录到 matcher 对象的属性 int[] groups 中,即记录 groups[0] = 0(因为 1998 中 1 的索引为 0),把该子字符串的结束的索引 + 1 的值记录到 groups[1] = 4。(为什么要记录索引 + 1呢?因为下面 matcher.group() 要调用 getSubSequence 进行截取字符串)
  3. 同时记录 oldLast 的值为 子字符串的结束的 索引 + 1 的值即 4, 即下次执行 find 时,就从 4 开始匹配

matcher.group(0) 分析:

首先看一下源码

 

这里我们只需要看第 8 行代码即可,注意我们传的参数的值是 0(因为 matcher.group(0)),再看第 8 行代码,很容易计算出 groups[group * 2] = groups[0] = 0,groups[group * 2 + 1] = groups[1] = 4

根据 groups[0] = 0 和 groups[1] = 4 的记录的位置,从 content 开始截取子字符串返回,就是 [0,4) 包含 0 但是不包含索引为 4 的位置(getSubSequence 的作用),再通过 toString() 返回,即 1998。

执行下一次循环,即先执行 matcher.find(),再执行 matcher.find() 。由于设定的字符串匹配规则,此时会定位到 1999 的位置。再次按照上面的规则来执行

  1. 根据指定的规则 ,定位满足规则的子字符串(比如 1999 )

  2. 找到后,将子字符串的开始的索引记录到 matcher 对象的属性 int[] groups;

    groups[0] = 31,把该子字符串的结束的索引 + 1 的值记录到 groups[1] = 35。

  3. 同时记录 oldLast 的值为 子字符串的结束的 索引+1的值即 35, 即下次执行 find 时,就从 35 开始匹配

再次执行 matcher.group(0)

由于传的参还是 0,故由

 

可知:groups[group * 2] = groups[0] = 31,groups[group * 2 + 1] = groups[1] = 35,故截取 [31,35)的字符串返回,即 1999

如果你有感觉到如果,不调用 matcher.group(0),而是调用 matcher.group(1),或者 matcher.group(2) 呢,那么说明你对正则表达式的理解更上一层了

什么是分组,比如 (dd)(dd) ,正则表达式中有() 表示分组,第1个()表示第1组,第2个()表示第2组…

 

matcher.find() 完成的任务 (考虑分组

  1. 根据指定的规则 ,定位满足规则的子字符串(比如(19)(98))

  2. 找到后,将 子字符串的开始的索引记录到 matcher 对象的属性 int[] groups 中

​ 2.1 groups[0] = 0 , 把该子字符串的结束的索引+1的值记录到 groups[1] = 4

​ 2.2 记录1组()匹配到的字符串 groups[2] = 0 groups[3] = 2

​ 2.3 记录2组()匹配到的字符串 groups[4] = 2 groups[5] = 4

​ 2.4.如果有更多的分组…

  1. 同时记录 oldLast 的值为 子字符串的结束的 索引+1的值即 4, 即下次执行 find 时,就从 4 开始匹配

image-20221109114411889

matcher.group()

 

调用 matcher.group(0) 时:由上面对 matcher.find() 的分析可知:groups[group * 2] = 0,groups[group * 2 + 1] = 4,由 getSubSequence 进行截取,,即返回 1998

调用 matcher.group(1) 时:由上面对 matcher.find() 的分析可知:groups[group * 2] = 0,groups[group * 2 + 1] = 2,由 getSubSequence 进行截取,,即返回 19

调用 matcher.group(2) 时:由上面对 matcher.find() 的分析可知:groups[group * 2] = 2,groups[group * 2 + 1] = 4,由 getSubSequence 进行截取,,即返回 98

运行结果

 

小结
如果正则表达式有 () 即分组,取出匹配的字符串规则如下

  1. group(0) 表示匹配到的子字符串
  2. group(1) 表示匹配到的子字符串的第一组字串
  3. group(2) 表示匹配到的子字符串的第2组字串
  4. … 但是分组的数不能越界,比如只有两个分组,但是却调用 matcher.group(3)

元字符

如果想要灵活的运用正则表达式,必须了解其中各种元字符的功能,元字符从功能上大致分为

  1. 限定符 ---- 限定字符的个数
  2. 选择匹配符 ----
  3. 分组组合和反向引用符
  4. 特殊字符
  5. 字符匹配符
  6. 定位符
元字符-转义号 \

\ 符号

说明:在我们使用正则表达式去检索某些特殊字符的时候,需要用到转义符号,否则检索不到结果,甚至会报错。

需要用到转移字符的有.*+()$/?[]^{}

 
元字符-字符匹配符

表中出现的 ?,*+ 等在元字符-限定符中有解释

符号含义实例解释
[ ]可接收的字符列表[efgh]e、f、g、h 中的任意 1 个字符
[ ^ ]不接收的字符列表[^abc]除 a、b、c 之外的任意 1 个字符,包括数字和特殊符号
-连字符A-Z任意单个大写字母
符号含义示例说明匹配输入
.匹配除 以外的任何字符a…b以 a 开头,b 结尾,中间包括 2 个任意字符的长度为 4 的字符串aaab、aefb、a35b、a#*b
\d匹配单个数字字符,相当于 [0-9]\d{3}(\d)?包含 3 个或 4 个数字的字符串123、9876
\D匹配单个非数字字符,相当于 [^0-9]\D(\d)*以单个非数字字符开头,后接任意个数字字符串a、A342
\w匹配单个数字、大小写字母字符,相当于 [0-9a-zA-Z]\d{3}\w{4}以 3 个数字字符开头的长度为7的数字字母字符串234abcd、12345Pe
\W匹配单个非数字、大小写字母字符,相当于 [^0-9a-zA-Z]\W+\d{2}以至少 1 个非数字字母字符开头,2 个数字字符结尾的字符串#29,#?@10
符号含义示例解释
|匹配"|"之前或之后的表达式ab|cdab 或者 cd
符号含义示例说明匹配输入
*指定字符重复 0 次或 n 次(无要求)零到多(abc)*仅包含任意个 abc 的字符串,等效于w*abc、abcabcabc
+指定字符重复 1次或 n 次(至少一次)1到多m+(abc)*以至少1个 m 开头,后接任意个 abc 的字符串m、mabc、mabcabc
?指定字符重复 0 次或 1 次(最多一次)0到1m+abc?以至少1个m开头,后接ab或abc的字符串mab、mabc、mmmab、mmabc
{n}只能输入 n 个字符[abcd]{3}由 abcd 中字母组成的任意长度为 3 的字符串abc、dbc、adc
{n,}指定至少 n 个匹配[abcd]{3,}由 abcd 中字母组成的任意长度不小于 3 的字符串aab、dbc、aaabdc
{n,m}指定至少 n 个但不多于 m 个匹配[abcd]{3,5}由 abcd 中字母组成的任意长度不小于 3 ,不大于 5 的字符串abc、abcd、aaaaa、bcdab
符号含义示例说明匹配输入
^指定起始字符+[a-z]*以至少 1 个数字开头,后接任意个小写字母的字符串123、6aa、555edf
$指定结束字符\-[a-z]+$以 1 个数字开头后接连字符"-",并以至少1 个小写字母结尾的字符串1-a
\b匹配目标字符串的边界zhu\b这里说的字符串的边界指的是子串间有空格,或者是目标字符串的结束位置zhuyierzuihaodezhu zzzhu
\B匹配目标字符串的非边界zhu\B和\b 的含义刚刚相反zhuyierzuihaodezhu zzzhu