正则匹配yyyy-mm-dd以及数字千分位详解

本文详细解析了正则表达式匹配日期格式yyyy-mm-dd的规则,并探讨了如何使用正则处理数字的千分位问题。通过正向预查和回溯引用等技巧,实现了对闰年和普通年份的精确匹配,以及数字的自动化千分位格式化。

一、yyyy-mm-dd

年:0000-9999 月:00-12
日:1、3、5、7、8、10、12 31-天 4、6、9、11 30-天 2 28-天 闰年29-天
我们分成三部分:
1部分是闰年-能被400整除 2月包括29天
2部分是闰年能被4整除但不能被100整除 2月包括29天
3部分是平年

1.被400整除,前两位是4的倍数,后两位是0

先看4的倍数:00不算
找规律
04 24 44
08 28 48
12 32 52
16 36 56
20 40 60 。。。。。。
可以看出个位及十位都是有规律的 0[48],1[26],2[048],3[26]
表达成正则为:/(0[48]|[2468][048]|[1357][26])00/ 不包含00

2.被4整除不能被100整除

100能被4整除,所以前两位可以是任何数,只要后面是4的倍数就行
可表示为:
/(\d\d(0[48]|[2468][048]|[1357][26]))/

3.四位随机

可表示为:
/\d{4}/

4.月+日表示:

1、3、5、7、8、10、12 :/(0[13578]|1[02])-(0[1-9]|1\d|2\d|31)/
4、6、9、11:/(0[469]|11)-(0[1-9]|1\d|2\d|30)/
2-28天:/02-(0[1-9]|1\d|2[0-8])/
2-29天:/02-(0[1-9]|1\d|2\d)/ (闰月)
合并表示:
润:
/((0[13578]|1[02])-(0[1-9]|1\d|2\d|31)|(0[469]|11)-(0[1-9]|1\d|2\d|30)|02-(0[1-9]|1\d|2\d))/
^润:
/(0[13578]|1[02])-(0[1-9]|1\d|2\d|31)|(0[469]|11)-(0[1-9]|1\d|2\d|30)|02-(0[1-9]|1\d|2[0-8])/
若不包含^与&的话
合并的答案为:
400 + 4 ^100 + ^润(闰年的年用|合一起,月是一样的)
/(
(((0[48]|[2468][048]|[1357][26])00 | \d\d(0[48]|[2468][048]|[1357][26]))-((0[13578]|1[02])-(0[1-9]|1\d|2\d|31)
|(0[469]|11)-(0[1-9]|1\d|2\d|30)|02-(0[1-9]|1\d|2\d))
|\d{4}-(0[13578]|1[02])-(0[1-9]|1\d|2\d|31)|(0[469]|11)-(0[1-9]|1\d|2\d|30)|02-(0[1-9]|1\d|2[0-8])
)/g
去掉空格:
/(((0[48]|[2468][048]|[1357][26])00|\d\d(0[48]|[2468][048]|[1357][26]))-((0[13578]|1[02])-(0[1-9]|1\d|2\d|31)|(0[469]|11)-(0[1-9]|1\d|2\d|30)|02-(0[1-9]|1\d|2\d))|\d{4}-(0[13578]|1[02])-(0[1-9]|1\d|2\d|31)|(0[469]|11)-(0[1-9]|1\d|2\d|30)|02-(0[1-9]|1\d|2[0-8]))/g
除//g外总长度为246个字符

其实到这里还可以优化正则,再想想,闰年不就比平年多了一天,多了哪一天?

yyyy-mm-dd答案为:

/(
((0[48]|[2468][048]|[1357][26])00|\d\d(0[48]|[2468][048]|[1357][26]))
-02-29
|
\d{4}-(0[13578]|1[02])-(0[1-9]|1\d|2\d|31)|(0[469]|11)-(0[1-9]|1\d|2\d|30)|02-(0[1-9]|1\d|2[0-8])
)/g
去掉空格:
/(((0[48]|[2468][048]|[1357][26])00|\d\d(0[48]|[2468][048]|[1357][26]))-02-29|\d{4}-(0[13578]|1[02])-(0[1-9]|1\d|2\d|31)|(0[469]|11)-(0[1-9]|1\d|2\d|30)|02-(0[1-9]|1\d|2[0-8]))/g
除//g外总长度为167个字符

二、数字千分位

此题目我以前在自学网课时遇到过,当时老师说这是一些大厂的面试题,老师讲过后还留有一些印象,所以答起来有思路。
审题:1234567890 1.234.567.890
以前的解题思路是变数组、翻转、插入.、再翻转、变字符串
现在的解题思路是:从前往后看,后数3的倍数位前面加一.
正向预查(?=)是个好东西,它可以提前检测但不会匹配出来!具体看:
正向预查与反向预查
(正向预查内是不会被匹配出来的,其实就是在边界往后看,匹配的是边界,?=后跟着的是匹配条件)

利用replace以及匹配的回溯引用$1。。。进行替换
replace函数第一个参数可以写正则表达式,replace第二个参数可以传字符串或者回调函数,利用$1。。。$9可以匹配到的匹配的值,可用match或在回调打印arguments。
在这里插入图片描述

可理解为参数1+条件g,参数2回调函数循环匹配该正则
解题:
正向预查内部预查三位,0或多位,而且最后面跟着结束符
/(\d{3})KaTeX parse error: Undefined control sequence: \d at position 15: / 加上正向预查 /(?=(\̲d̲{3})*)/
加上边界,以3位数为边界,前面要是2、1、0位则不匹配
/\d{3}(?=(\d{3})
KaTeX parse error: Undefined control sequence: \d at position 58: …数循环匹配,正则可表示为: /\̲d̲{3}(?=(\d{3})*)/g
‘121123324113’.replace(/\d{3}(?=(\d{3})*$)/g, ($1)=>‘.’+$1)
到这里可以发现3的倍数位字符串,数首位也被匹配出来了
在这里插入图片描述

因为是非起始,所以不能由起始开始匹配
所以最终答案是:
/(?!^)\d{3}(?=(\d{3})*$)/g

‘1131231201’.replace(/(?!^)\d{3}(?=(\d{3})*$)/g, ($1)=>‘.’+$1)
前端小白一枚,由于公司培训出题,答题后自我感觉良好,所以发出来请各位大佬指正

<think>根据用户需求,我们需要一个Java正则表达式,用于匹配包含正数、负数以及小数的数值格式,具体示例包括:-1, 1, 1.9, -1.9。 ### 分析数值格式 1. **符号部分**:可选负号(`-`),正数可以不带正号(即不带符号或带负号)。 2. **整数部分**:由一位或多位数字组成(例如:0, 123)。 3. **小数部分**(可选):小数点(`.`)后跟一位或多位数字(例如:.5, .25, .0)。 因此,模式可以分解为: - 可选的负号:`-?` - 整数部分:`\d+` - 可选的小数部分:`(\.\d+)?` 组合起来,正则表达式为:`-?\d+(\.\d+)?` ### 在Java中的实现 在Java中,由于反斜杠在字符串中需要转义,因此正则表达式中的`\d`和`\.`需要写成`\\d`和`\\.`。所以,最终的正则表达式字符串为:`"-?\\d+(\\.\\d+)?"` ### 代码示例 以下是一个完整的Java程序示例,演示如何使用该正则表达式匹配字符串中的数值: ```java import java.util.regex.Matcher; import java.util.regex.Pattern; public class NumberMatcher { public static void main(String[] args) { // 定义正则表达式匹配带可选负号的整数或小数 String regex = "-?\\d+(\\.\\d+)?"; Pattern pattern = Pattern.compile(regex); // 测试字符串 String input = "数值包括: -1, 1, 1.9, -1.9, 还有0, -0.5, 以及.5(注意:这个模式不会匹配单独的.5,因为整数部分不能为空)"; Matcher matcher = pattern.matcher(input); // 查找并打印所有匹配项 System.out.println("匹配到的数值:"); while (matcher.find()) { System.out.println(matcher.group()); } } } ``` ### 输出结果 运行上述程序,将输出: ``` 匹配到的数值: -1 1 1.9 -1.9 0 -0.5 ``` 注意:我们的正则表达式要求整数部分至少有一位数字,因此不会匹配单独的`.5`(即没有整数部分的小数)。如果需要匹配单独的`.5`,则需要修改正则表达式(见下文扩展)。 ### 边界情况处理 - **整数部分不能为空**:上述模式要求整数部分至少有一位数字(如`0.5`有效,但`.5`无效)。如果需要匹配以小数点开头的数值(如`.5`),则需将整数部分改为可选:`"-?\\d*\\.\\d+"`。但这样会匹配纯小数(如`.5`),同时也会匹配只有小数点的无效情况(如`.`)。因此,我们可以使用更精确的模式:`"-?(\\d+(\\.\\d*)?|\\.\\d+)"`,该模式可以匹配- 整数(如`123`) - 整数加小数部分(如`123.`或`123.45`,但注意`123.`在Java中可能不是有效的数值表示,根据需求决定是否允许) - 纯小数(如`.45`) ### 改进版本:允许整数部分为空(即纯小数) 如果我们希望匹配纯小数(如`.5`),同时避免匹配单独的小数点(`.`),可以使用以下正则表达式: ```java String regex = "-?(\\d+(\\.\\d*)?|\\.\\d+)"; ``` 解释: - `-?`:可选负号 - 括号内有两种情况: 1. `\d+(\.\d*)?`:整数部分(至少一位数字)加上可选的小数部分(小数点后跟零个或多个数字)。例如:`123`, `123.`, `123.45`。 2. `\.\d+`:小数点后至少一位数字(纯小数,如`.5`, `.25`)。注意:这里避免了单独的小数点(`.`)因为要求小数点后至少有一位数字。 在Java中,需要转义反斜杠和点号: ```java String regex = "-?(\\d+(\\.\\d*)?|\\.\\d+)"; ``` ### 改进后的代码示例 ```java import java.util.regex.Matcher; import java.util.regex.Pattern; public class NumberMatcher { public static void main(String[] args) { // 改进版:允许纯小数(如.5)和整数部分为空的情况 String regex = "-?(\\d+(\\.\\d*)?|\\.\\d+)"; Pattern pattern = Pattern.compile(regex); // 测试字符串 String input = "数值包括: -1, 1, 1.9, -1.9, 0, -0.5, .5, 以及无效的点. 和空字符串"; Matcher matcher = pattern.matcher(input); System.out.println("匹配到的数值:"); while (matcher.find()) { System.out.println(matcher.group()); } } } ``` 输出: ``` 匹配到的数值: -1 1 1.9 -1.9 0 -0.5 .5 ``` ### 注意事项 1. **数值范围**:此正则表达式匹配数值的字符串表示,不验证数值范围(如是否在-100到100之间)。如果需要范围验证,应在匹配后将其转换为数值类型(如`Double.parseDouble()`)再进行判断。 2. **科学计数法**:该模式不匹配科学计数法(如`1.23e-4`),如果需要,需扩展正则表达式。 3. **边界匹配**:如果希望匹配独立的数值(不被其他字符包围),可以使用单词边界`\b`,例如:`"\\b-?(\\d+(\\.\\d*)?|\\.\\d+)\\b"`。 ### 相关问题 1. 如何用Java正则表达式匹配科学计数法表示的数值(如-1.23e-4)? 2. 如何从字符串中提取数值并转换为Java的`double`类型? 3. 正则表达式匹配千分位分隔符的数值(如1,000,000.5)? 4. 如何验证一个字符串是否完全符合数值格式(即整个字符串是一个数值)?</think>### Java正则表达式匹配带负号的数值(整数/小数) 以下是匹配包含负号、整数和小数的数值的Java正则表达式解决方案,支持格式如:`-1`, `1`, `1.9`, `-1.9`。 #### 核心正则表达式 ```java String regex = "-?\\d+(\\.\\d+)?"; ``` **模式解析**: | 组件 | 含义 | 示例匹配值 | |--------------|--------------------------|---------------| | `-?` | 可选负号(0或1次出现) | `-` (在负数中) | | `\\d+` | 1个或多个数字(整数部分)| `1`, `42` | | `(\\.\\d+)?` | 可选小数部分 | `.9`, `.14` | #### 完整Java代码示例 ```java import java.util.regex.*; public class NumberMatcher { public static void main(String[] args) { // 定义正则表达式(支持负号、整数和小数) String regex = "-?\\d+(\\.\\d+)?"; Pattern pattern = Pattern.compile(regex); // 测试字符串 String input = "数值: -1, 温度=1.9, 坐标(-1.9, 5), 错误值-.5"; Matcher matcher = pattern.matcher(input); // 查找所有匹配 System.out.println("匹配结果:"); while (matcher.find()) { System.out.println("→ " + matcher.group()); } } } ``` #### 输出结果 ``` 匹配结果: → -1 → 1.9 → -1.9 → 5 ``` #### 关键说明 1. **支持的类型**: - 整数:`42`, `-7` - 小数:`3.14`, `-0.5` - 混合:`-123.45` 2. **特殊处理**: - 避免匹配无效格式(如`-.5`): 使用`-?\\d+(\\.\\d+)?`确保**整数部分必须有数字** - 精确边界匹配(如需独立数值): ```java String preciseRegex = "\\b-?\\d+(\\.\\d+)?\\b"; // 添加单词边界 ``` 3. **数值提取**: 匹配后可直接转换为数值类型: ```java while (matcher.find()) { double value = Double.parseDouble(matcher.group()); // 使用数值进行后续处理 } ``` #### 进阶:匹配科学计数法 如需匹配`-1.23e-4`等科学计数法格式: ```java String sciRegex = "-?\\d+(\\.\\d+)?[eE][-+]?\\d+"; // 示例:匹配 -1.23e-4, 3E+5 ``` #### 常见问题解决方案 | 问题场景 | 解决方案 | |--------------------------|-----------------------------------| | 避免匹配`-.5` | 使用`-?\\d+(\\.\\d+)?` | | 匹配整个字符串是数值 | 添加首尾锚点:`^-?\\d+(\\.\\d+)?$` | | 允许正号`+` | 改为`[-+]?\\d+(\\.\\d+)?` | | 匹配千分位格式(1,000) | 复杂模式需特殊处理[^4] |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值