遇到一个正则表达会的问题,暂时未找到理论上的支持,所以先在此记录,待后慢慢解决
public static void main(String [] ben){ System.out.println("12345".replaceAll(".*", "a")); }
关于这行语句,大家试想下输出会是什么?我一开始分析答案可能是以下两个:
- 答案一:aaaaa
- 答案二:a
因为牵涉到正则表达式的贪婪匹配和非贪婪匹配,查阅资料得知*应该是贪婪匹配,所以我在没有执行上述代码的时候,得出应该是答案二。但是执行后的结果却让人大跌眼镜,是aa.
网上查阅资料无果,只有自己看源码了:
/** * String的replaceAll方法 **/ public String replaceAll(String regex, String replacement) { return Pattern.compile(regex).matcher(this).replaceAll(replacement); } /** * Matcher的replaceAll方法 **/ public String replaceAll(String replacement) { reset(); boolean result = find(); if (result) { StringBuffer sb = new StringBuffer(); do { appendReplacement(sb, replacement); result = find(); } while (result); appendTail(sb); return sb.toString(); } return text.toString(); }
既然执行结果是两个a,那么我猜测是find()有两次执行结果是ture.所以模拟代码
public static void main(String[] ben){ Pattern pattern = Pattern.compile(".*", Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher("12345"); int i=0; while(matcher.find()){ System.out.println("循环:"+i+"次"); i++; System.out.println(matcher.group()); } }
执行结果为:
循环:0次
12345
循环:1次
也就是说.*先最长匹配了12345,然后又匹配了一个空字符,其实没有能够仔细的分析到代码,所以现在只能猜测,也只有等有能力的时候再仔细分析代码。
猜测过程应该如下:
- 首先从第一个位置开始匹配,*是最长匹配,所以一直匹配到12345成功位置
- 然后再从第六个位置开始匹配,发现第六个位置已经是最后个位置了,此时取出的子匹配串是空的,.*是匹配.0个到多个,也就是0个也是可以满足的,所以这里也匹配成功了
-
匹配结束,总共匹配两次成功!
同样,.+也是贪婪匹配,但是如果使用.+的话,只会循环一次,输出12345,因为上述2过程匹配不会成功。所以我们在使用的时候,要谨慎使用*这个匹配符。
在寻找答案的过程中,发现一篇好文章,虽然对于解答此文的疑问用处不大:
来自淘宝综合业务部门的技术博客:Java正则引发的思考。
相关推荐
常用正则表达式-常用正则表达式-常用正则表达式 常用正则表达式-常用正则表达式-常用正则表达式
Java正则表达式详解-软件频道-正则表达式-天极网
- **分组**:使用圆括号`()`将正则表达式的一部分内容括起来形成一个分组。 - **分组编号**:每个分组都会自动获得一个编号,从左到右依次为1,2,3,...。例如,`(abc)(def)`中有两个分组,第一个分组是`abc`,编号为1...
Pattern类是Java正则表达式的起点,它将一个正则表达式编译成一个模式对象。这个编译过程可以优化后续的匹配操作。例如,创建Pattern对象的代码如下: ```java Pattern pattern = Pattern.compile("正则表达式"); `...
这可能是一个包含正则表达式教程的演示文稿,可能涵盖了更复杂的概念,如预查`(?=...)`和否定预查`(?!...)`,或者后向引用`\number`,以及非捕获组 `(?:...)`。 5. **JAVA正则表达式--Pattern和Matcher.doc** 这...
接着,定义了一个名为`SocialSecurityNumberValidator`的类,在主方法中使用`Pattern.compile`编译正则表达式,并使用`matcher.matches`来检查字符串是否与给定的模式匹配。 通过上述知识点的学习,读者可以了解到...
- **Pattern类**:用于编译正则表达式,创建一个Pattern对象。这一步是对正则表达式进行预处理,提高后续匹配效率。 - **Matcher类**:用于将正则表达式应用到具体的文本上,进行匹配操作。 #### 五、示例详解 为了...
提取URL,正则表达式 - C# - 开发者参考网提取URL,正则表达式 - C# - 开发者参考网提取URL,正则表达式 - C# - 开发者参考网提取URL,正则表达式 - C# - 开发者参考网提取URL,正则表达式 - C# - 开发者参考网提取URL,...
`在正则表达式中具有特殊含义,分别代表零个或多个、一个或多个、零个或一个前一个字符。 4. **范围处理** - 使用方括号`[]`定义字符范围,例如`[a-zA-Z]`表示匹配任何字母。 5. **预定义字符类** - `\s`:匹配...
Java使用正则表达式提取XML节点内容的方法示例是一个非常有用的技术,可以帮助开发者快速提取XML节点内容。但是,为了更好地掌握这个技术,开发者需要具备一定的基础知识和经验,并且需要具备一定的实践经验。
Java 第三阶段增强分析需求,代码实现能力【正则表达式】---- 代码 Java 第三阶段增强分析需求,代码实现能力【正则表达式】---- 代码 Java 第三阶段增强分析需求,代码实现能力【正则表达式】---- 代码 Java 第三...
1. **编译正则表达式**:使用`Pattern.compile()`方法创建一个`Pattern`对象,例如`Pattern pattern = Pattern.compile("你的正则表达式")`。 2. **创建Matcher对象**:使用`Pattern`对象的`matcher()`方法,传入...
### 使用Java正则表达式实现一个简单的身份证号码验证 #### 一、背景介绍 身份证号码是中国公民的身份标识,由15位或18位数字组成(早期为15位,后改为18位)。其中,第18位是校验码,可能是数字0~9或者大写字母X。...
例如,你可以使用`Pattern.compile("正则表达式")`来创建一个`Pattern`实例。 接着是`Matcher`类,它是`Pattern`的实例,用于对输入字符串进行实际的匹配、查找、替换等操作。`Matcher`提供了诸如`matches()`、`...
另一个实例是匹配不包含连字符的社会安全号码,如`999999999`,正则表达式可以是`[0-9]{9}`,这将匹配任何9位的数字串。 除此之外,正则表达式还有更多的高级特性,如预查(`(?=...)`)、后顾(`(?!...)`)、分组...
Java正则表达式是编程语言Java中的一个强大工具,它用于模式匹配、数据验证和文本检索替换。在Java中,正则表达式是通过java.util.regex包提供的接口和类来实现的。`regex-smart.jar`这个库显然是为了简化开发者在...
Pattern类是正则表达式的编译表示形式,它将正则表达式编译成一个模式,使其可以被Matcher类使用。Matcher类是负责进行匹配的类,它将字符串与模式进行比较,以确定是否匹配。 在这个示例中,我们使用 Pattern....
本话题聚焦于如何利用Java来生成一个正则表达式,这个表达式能够验证一个字符串是否代表了在特定范围内的浮点数。浮点数包括整数部分、小数部分以及可能存在的正负号。这里的"最小最大值"指的是浮点数的范围,例如,...
这个合集提供的HTML和Java正则表达式实例,为开发者提供了一个快速参考的工具,帮助他们在开发过程中快速有效地实现数据验证功能。理解并熟练运用这些正则表达式,对于提高代码质量和用户体验都有极大的帮助。在实际...