Java时间段解析:正则表达式规则调整需求(含可选字符串)
Java Regex for Time Period Parsing (With Updated Rules)
Alright, let's refine that regex for your Java time period parsing scenario. Your updated rules make total sense—let's break down how to implement them correctly.
Core Rules Recap
First, let's restate your requirements to align on what we're building:
- Input format:
<time> [optional string]where<time>usesdfor days,hfor hours,mfor minutes - Must satisfy one of these:
- Includes the minutes group (
m), with or without days/hours - Includes at least days (
d) or hours (h) (no minutes required in this case)
- Includes the minutes group (
- All valid time combinations are allowed (e.g.,
d only,h only,d+h,d+m,h+m,d+h+m)
Final Regex Pattern
Here's the regex that enforces these rules:
^(?:(?=.*\d+m)|(?=.*\d+d)|(?=.*\d+h))(?:(\d+)d)?(?:(\d+)h)?(?:(\d+)m)?(?:\s+(.+))?$
Breakdown of the Regex
Let's walk through each part to understand how it works:
^/$: Anchors to match the entire input string (prevents partial matches)(?=.*\d+m)|(?=.*\d+d)|(?=.*\d+h): Positive lookahead that ensures at least one valid time component exists (minutes, days, or hours). This is the key to enforcing your "minimum requirement" rule.(?:(\d+)d)?: Optional days group—captures one or more digits followed byd(the?makes it optional)(?:(\d+)h)?: Optional hours group—same logic as days(?:(\d+)m)?: Optional minutes group—same logic as days/hours(?:\s+(.+))?$: Optional trailing string—captures any text after one or more spaces (the?makes this entire section optional)
Valid & Invalid Examples
Let's test the pattern against common cases:
Valid Inputs
30m(minutes only)2d(days only)5h(hours only)1d 2h(days + hours, no minutes)1d 30m(days + minutes)2h 15m(hours + minutes)1d 2h 30m(all three components)1d 2h 30m Fix login flow(time + optional string)
Invalid Inputs
- Empty string (no time components)
Just a string(no time components)0d(if you want to disallow zero values—see note below)
Java Implementation Example
Here's how you can use this regex in Java to parse and extract the components:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class TimePeriodParser { // Compile the pattern once for efficiency private static final Pattern TIME_PERIOD_PATTERN = Pattern.compile( "^(?:(?=.*\\d+m)|(?=.*\\d+d)|(?=.*\\d+h))(?:(\\d+)d)?(?:(\\d+)h)?(?:(\\d+)m)?(?:\\s+(.+))?$" ); public static void parseTimePeriod(String input) { Matcher matcher = TIME_PERIOD_PATTERN.matcher(input); if (matcher.matches()) { // Extract captured groups (will be null if the component wasn't present) String days = matcher.group(1); String hours = matcher.group(2); String minutes = matcher.group(3); String description = matcher.group(4); System.out.println("Parsed Time Period:"); if (days != null) System.out.println("Days: " + days); if (hours != null) System.out.println("Hours: " + hours); if (minutes != null) System.out.println("Minutes: " + minutes); if (description != null) System.out.println("Description: " + description); } else { System.out.println("Invalid input: '" + input + "' does not match the required format."); } } public static void main(String[] args) { // Test cases parseTimePeriod("30m"); parseTimePeriod("2d"); parseTimePeriod("1d 2h 30m Fix login flow"); parseTimePeriod("Just a string"); // Invalid } }
Optional Enhancement: Disallow Zero Values
If you want to prevent inputs like 0d or 0h (since zero days/hours/minutes don't make sense for a time period), adjust the regex to use [1-9]\d* instead of \d+ to enforce positive integers:
^(?:(?=.*[1-9]\d*m)|(?=.*[1-9]\d*d)|(?=.*[1-9]\d+h))(?:([1-9]\d*)d)?(?:([1-9]\d*)h)?(?:([1-9]\d*)m)?(?:\s+(.+))?$
内容的提问来源于stack exchange,提问作者peter Schiza
相关产品推荐
相关产品推荐

