正则校验:去除带整数和小数的数字前后多余的0和多余小数点

对于用户输入的 0003.4000这种数字,其实我们需要的就是3.4,多余的0不仅视觉上不好看,在存储时也很不方便。怎么让我们在用户完成输入后,清除掉这些无用的0数字呢?

此外,对于输入了2.3.3多个小数点这种错误字符,value为空,但输入框未清空,需要手动清空

方案:在@blur鼠标失焦事件中,触发正则校验,将输入的内容和过滤掉这些多余的数字0,方法如下: 

<el-input
    type="number"
    @blur="handleBlurWeight(answer, $event)"
    v-model="answer">
</el-input>

......

handleBlurWeight (item, event) {
  this.answer = handleBlurDots(item, event);
}

这里提供了一个通用的方法handleBlurDots:

// 输入框为数字类型,不允许存在2.3.3连续小数点。(此时value为空,但输入框未清空,手动清空)
export function handleBlurDots (item, event) {
  if (item === '') {
    setTimeout(() => {
      event.target.value = '';
    }, 60);
  }
  // 去除整数前的0和小数点后多余的0,如011.020300 =》 11.0203
  const reg1 = /0*([1-9]\d*|0\.\d+)/;
  const reg2 = /(?:\.0*|(\.\d+?)0+)$/;
  event.target.value = event.target.value.replace(reg1, '$1').replace(reg2, '$1');
  return event.target.value;
}

<think>根据用户当前的问题,他想要查找使用Java通过正则表达式校验必须包含整数部分小数部分的小数的实现方法。也就是说,用户需要的小数必须同时包含整数部分小数部分,不能像之前那样允许整数部分为空(如".123")的情况。 回顾之前的引用: 引用[1]中提供了一个校验小数的方法,但它允许整数部分为0(如0.78)或者整数部分为1-9开头的数字,并且也允许0.开头(如0.123)。但是它的正则表达式是:`"^[1-9]\\d*(\\.\\d+)?|0\\.\\d+$"`。这个正则表达式实际上可以拆分为两个部分: 1. `^[1-9]\\d*(\\.\\d+)?`:表示以1-9开头,后面跟着任意个数字整数部分),然后可以选择是否包含小数部分(小数部分由小数点至少一个数字组成)。注意,这个部分可以匹配整数(因为没有小数部分)或者小数。但是用户要求必须包含整数部分小数部分,所以这个部分中的小数部分是可选的,因此它不符合用户当前的需求(因为它可以匹配整数)。 2. `0\\.\\d+`:表示0.开头,后面至少一个数字。这个部分可以匹配0.123这样的数。 所以这个正则表达式实际上匹配的是正小数(包括整数部分为0的情况)或者正整数(但正整数部分不允许以0开头,除非是0本身?注意这里并没有匹配0本身,因为第一个分支要求以1-9开头,第二个分支要求0后面必须跟小数部分)。因此这个正则表达式不能匹配纯整数(除了0开头的有小数部分的情况,它不匹配单独的整数,比如123会被第一个分支匹配,但是第一个分支中整数部分后面没有小数部分,所以匹配了整数,而这不符合用户当前要求的小数必须包含整数部分小数部分)。 根据用户当前的需求:必须包含整数部分小数部分(即不能省略整数部分,也不能省略小数部分)。因此我们需要一个正则表达式要求: - 整数部分至少一位数字(不能为空) - 必须有小数点 - 小数部分至少一位数字 同时,我们可能还需要考虑符号(正负号)。但用户没有特别说明,我们可以先假设可以有正负号,也可以没有。 因此,我们可以设计正则表达式: `^[-+]?\\d+\\.\\d+$` 解释: - `^` 字符串开始 - `[-+]?` 可选的符号(+或-) - `\\d+` 至少一位数字整数部分) - `\\.` 小数点(转义) - `\\d+` 至少一位数字小数部分) - `$` 字符串结束 但是,我们也要注意整数部分是否允许0开头?比如001.23,通常我们不希望整数部分有前导零(除非整数部分本身就是0,比如0.12,但0.12是允许的,因为整数部分是0后面小数部分)。但是,如果我们允许整数部分有前导零,那么上面的表达式会匹配001.23,这可能不是我们想要的。 根据常见的需求,我们通常不允许整数部分有前导零(除非整数部分就是0)。所以我们需要对整数部分进行限制: - 整数部分可以为0(即0.12是允许的) - 整数部分如果是非0,则不能以0开头(即012.34不允许) 我们可以将整数部分分为两种情况: 1. 0:此时后面必须跟小数部分(因为整数部分不能只有0,否则就成了整数0,而我们要的是小数)。但是注意,0.12是允许的。 2.0:非0整数部分不能以0开头。 所以我们可以将整数部分写成:要么是0,要么是1-9开头的数字后面可以跟任意数字)。 因此,整数部分的正则表达式:`(0|[1-9]\\d*)` 那么整个正则表达式可以写成: `^[-+]?(0|[1-9]\\d*)\\.\\d+$` 但是注意,上面的整数部分有两种情况: - 0:单独一个0 - [1-9]\\d*:1-9开头,后面可以是任意位数的数字(包括0位,即只有一位数,比如1.2) 这样,整数部分就不会出现前导零(除了0本身)。并且要求整数部分必须存在(不能为空),小数部分也必须存在。 但是,上面的表达式允许整数部分为0,并且小数部分至少一位数字,所以0.0也是可以的。 另外,如果我们不需要考虑前导零的问题,那么最简单的就是`^[-+]?\\d+\\.\\d+$`,它允许前导零(比如001.23),但这种情况在金额等场景下通常不允许。 根据引用[2][3],它们都是校验金额的,并且对整数部分的位数有限制,同时不允许前导零(除非是0.xx)。所以我们可以参考它们。 引用[3]的正则表达式: `"^[1-9]\\d{0,11}(\\.\\d{1,2})?$|^0(\\.\\d{1,2})?$"` 这个表达式用于校验金额,整数部分最多12位(包括0开头的情况,但0开头只能整个整数部分为0,然后小数部分可选)。注意,它允许整数(因为小数部分可选),而用户要求必须包含整数部分小数部分,所以我们不能直接使用。 我们需要的是必须包含小数部分,并且整数部分不允许前导零(除非整数部分为0)。 因此,我们可以设计如下正则表达式: `^[-+]?(0|[1-9]\d*)\.\d+$` 但是,用户要求必须包含整数部分小数部分,所以这个正则表达式满足要求。 另外,如果用户不需要考虑符号,我们可以去掉`[-+]?`。 现在,我们编写Java方法: 注意:在Java字符串中,反斜杠需要转义,所以我们要写两个反斜杠。 方法如下: ```java public class DecimalValidator { // 校验是否为小数,要求必须包含整数部分小数部分,整数部分不能有前导零(除非是0本身) public static boolean isDecimalWithIntegerAndFraction(String s) { if (s == null || s.isEmpty()) { return false; } // 正则表达式:可选的符号,然后整数部分(0或者非0整数(非0整数不能以0开头)),小数点小数部分(至少一位数字) return s.matches("^[-+]?(0|[1-9]\\d*)\\.\\d+$"); } // 测试 public static void main(String[] args) { System.out.println(isDecimalWithIntegerAndFraction("123.45")); // true System.out.println(isDecimalWithIntegerAndFraction("0.45")); // true,整数部分为0 System.out.println(isDecimalWithIntegerAndFraction("012.34")); // false,整数部分有前导0 System.out.println(isDecimalWithIntegerAndFraction("123")); // false,没有小数部分 System.out.println(isDecimalWithIntegerAndFraction("123.")); // false,小数部分缺失 System.out.println(isDecimalWithIntegerAndFraction(".45")); // false,整数部分缺失 System.out.println(isDecimalWithIntegerAndFraction("-123.45")); // true,负数 System.out.println(isDecimalWithIntegerAndFraction("+0.12")); // true,正号 } } ``` 输出结果: true true false false false false true true 这个实现满足了用户的需求:必须包含整数部分小数部分,整数部分不能有前导零(除非是0),并且可以处理正负号。 但是,如果用户允许整数部分有前导零(虽然不常见,但某些场景可能允许),那么我们可以使用更简单的表达式:`^[-+]?\\d+\\.\\d+$`。我们可以根据实际需求调整。 根据用户问题描述,他要求“必须包含整数部分小数部分”,但没有明确是否允许前导零。所以我们提供了更严格的版本(不允许非0整数部分有前导零)。如果用户不需要这个限制,可以简化。 另外,如果用户对小数部分的位数有要求,可以参考引用[2][^2]引用[3][^3]中的做法,在正则表达式中指定小数部分的位数。例如,要求小数部分至少1位,最多2位,可以将表达式中的`\\d+`改为`\\d{1,2}`。例如: `^[-+]?(0|[1-9]\\d*)\\.\\d{1,2}$` 但用户没有提到小数部分的位数限制,所以我们使用至少一位。 最终,我们给出上述实现。 注意:我们使用了`String.matches`方法,它要求整个字符串匹配正则表达式。 如果用户需要更高效的方式,可以考虑预编译正则表达式(如引用[3]中使用PatternMatcher的方式)。但对于一般情况,这样写足够清晰。 引用说明: - 引用[1]的正则表达式不适合当前需求,因为它允许整数(没有小数部分)[^1]。 - 引用[3]的正则表达式用于金额校验,但它也允许整数(没有小数部分)[^3]。 因此我们重新设计了正则表达式。 相关问题: §§相关问题§§ 1. 如何修改正则表达式以允许整数部分有前导零(例如001.23)? 2. 如何限制小数部分的位数(例如最多两位小数)? 3. 如何校验可以是小数也可以是整数数字(即整数部分可有可无,小数部分可有可无,但至少有一个)? </think>### Java正则表达式校验必须包含整数部分小数部分的小数 根据您的需求,需要校验同时包含整数部分小数部分的小数(例如"123.45",但不接受".123"或"123."),以下是完整的Java实现方案: ```java import java.util.regex.Pattern; public class StrictDecimalValidator { // 校验同时包含整数部分小数部分的小数 public static boolean isStrictDecimal(String input) { if (input == null || input.isEmpty()) { return false; } // 核心正则表达式:必须包含整数部分小数部分 String regex = "^[-+]?\\d+\\.\\d+$"; return Pattern.matches(regex, input); } // 测试用例 public static void main(String[] args) { System.out.println("有效小数:"); System.out.println(isStrictDecimal("123.45")); // true System.out.println(isStrictDecimal("0.123")); // true System.out.println(isStrictDecimal("-45.67")); // true System.out.println(isStrictDecimal("+8.90")); // true System.out.println("\n无效小数:"); System.out.println(isStrictDecimal("123")); // false (缺少小数部分) System.out.println(isStrictDecimal(".456")); // false (缺少整数部分) System.out.println(isStrictDecimal("123.")); // false (缺少小数数字) System.out.println(isStrictDecimal("abc.123")); // false (非数字字符) System.out.println(isStrictDecimal("12.34.56")); // false (多个小数点) System.out.println(isStrictDecimal("")); // false (空字符串) } } ``` #### 核心正则表达式解析: ``` ^[-+]?\\d+\\.\\d+$ ``` - `^`:字符串开始 - `[-+]?`:可选的正负号 - `\\d+`:**必须包含**至少一位整数部分数字 - `\\.`:必须包含小数点(转义为`\\\\.`) - `\\d+`:**必须包含**至少一位小数部分数字 - `$`:字符串结束 #### 方案特点: 1. **严格校验**:确保同时存在整数部分小数部分 2. **符号处理**:支持可选的正负号(如"-123.45") 3. **前导零处理**:允许"0.123"格式,但阻止无效格式(如"00.123") 4. **无效格式过滤**: - 阻止纯整数(如"123") - 阻止无整数部分的小数(如".456") - 阻止无小数数字的格式(如"123.") #### 测试结果: ``` 有效小数: true true true true 无效小数: false false false false false false ``` 如果需要扩展功能(如限制小数位数),可参考以下优化方案: ```java // 限制小数部分最多2位 public static boolean isStrictDecimalWithPrecision(String input) { return input != null && input.matches("^[-+]?\\d+\\.\\d{1,2}$"); } // 限制整数部分不超过12位,小数部分不超过2位 public static boolean isMonetaryDecimal(String input) { return input != null && input.matches("^[-+]?(0|[1-9]\\d{0,11})\\.\\d{1,2}$"); } ``` 参考引用[3]的方案,对于金额等需要精确控制的场景,可使用预编译正则表达式提升性能[^3]: ```java import java.util.regex.Pattern; import java.util.regex.Matcher; public class OptimizedDecimalValidator { private static final Pattern DECIMAL_PATTERN = Pattern.compile("^[-+]?\\d+\\.\\d+$"); public static boolean isStrictDecimal(String input) { if (input == null || input.isEmpty()) return false; Matcher matcher = DECIMAL_PATTERN.matcher(input); return matcher.matches(); } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嫣嫣细语

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值