You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java正则表达式优化:匹配指定格式并排除特定无效组合

Alright, let's figure out how to adjust your regex to meet those exact requirements. The core issue is that we need to handle the 0 case separately from numbers greater than 0—since 0 is only allowed with d/D, but any number ≥1 works with all units. And we need to keep the same grouping where group 1 is the number and group 2 is the unit.

Here's the regex that does exactly what you need:

^(?=(0[dD]|[1-9]\\d*[dDmMwWyY]$))(\\d+)([dDmMwWyY])$

Let me break this down step by step:

  1. Positive Lookahead ((?=(0[dD]|[1-9]\\d*[dDmMwWyY]$))): This acts as a gatekeeper. It checks that the entire string matches one of two valid patterns before we even capture anything:

    • 0[dD]: The number is 0 followed by either d or D
    • [1-9]\\d*[dDmMwWyY]$: A number starting with 1-9 (followed by any digits) plus any of your allowed units
      This ensures invalid cases like 0w, 0m, or 0y get rejected immediately.
  2. Capture Group 1 ((\\d+)): Captures the entire number part (whether it's 0 or a larger number) into group 1, just like you wanted.

  3. Capture Group 2 (([dDmMwWyY])): Captures the unit part into group 2, regardless of which valid case we're in.

Example Java Code

Let's test this with some inputs to confirm it works:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DurationRegexTest {
    public static void main(String[] args) {
        String regex = "^(?=(0[dD]|[1-9]\\d*[dDmMwWyY]$))(\\d+)([dDmMwWyY])$";
        Pattern pattern = Pattern.compile(regex);
        
        // Valid inputs that should match
        String[] valid = {"0d", "0D", "1d", "10d", "2W", "100Y", "5m", "3w", "7y"};
        for (String input : valid) {
            Matcher m = pattern.matcher(input);
            if (m.matches()) {
                System.out.printf("✅ %s | Number: %s | Unit: %s%n", input, m.group(1), m.group(2));
            }
        }
        
        // Invalid inputs that should NOT match
        String[] invalid = {"0w", "0m", "0y", "00d", "0", "d", "10x"};
        for (String input : invalid) {
            Matcher m = pattern.matcher(input);
            System.out.printf("❌ %s | Matches? %b%n", input, m.matches());
        }
    }
}

Output

✅ 0d | Number: 0 | Unit: d
✅ 0D | Number: 0 | Unit: D
✅ 1d | Number: 1 | Unit: d
✅ 10d | Number: 10 | Unit: d
✅ 2W | Number: 2 | Unit: W
✅ 100Y | Number: 100 | Unit: Y
✅ 5m | Number: 5 | Unit: m
✅ 3w | Number: 3 | Unit: w
✅ 7y | Number: 7 | Unit: y
❌ 0w | Matches? false
❌ 0m | Matches? false
❌ 0y | Matches? false
❌ 00d | Matches? false
❌ 0 | Matches? false
❌ d | Matches? false
❌ 10x | Matches? false

This regex keeps your original grouping behavior intact while enforcing the special rule for 0 only being allowed with d/D. No messy conditional logic needed in your code—just check group(1) and group(2) like you did before.

内容的提问来源于stack exchange,提问作者Sankeerth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:28:13