I have a question about regexes in Java, though I think this might apply to other languages as well.
我对Java中的正则表达式有疑问,但我认为这也可能适用于其他语言。
I have a regex to parse time from a field where user may enter something like 4d 8h 42m
. Of course, I want to make it as flexible as possible, so that user should not be obliged to type all numbers (and enter a mere 15h
for instance).
我有一个正则表达式来解析用户可能输入4d 8h 42m之类的字段的时间。当然,我想让它尽可能灵活,这样用户就不必*输入所有数字(例如输入仅15h)。
My regex is quite satisfactory concerning that point: (?:([\d]+)d)?[\s]*(?:([\d]+)h)?[\s]*(?:([\d]+)m)?
关于这一点我的正则表达式是相当令人满意的:(?:([\ d] +)d)?[\ s] *(?:( [\ d] +)h)?[\ s] *(?:( [ \ d] +)M)?
Now my problem is that it will also match an empty string, though I would like it to ensure that at least one time-unit is filled.
现在我的问题是它也将匹配一个空字符串,但我希望它确保至少填充一个时间单位。
The current solution would be to arbitrary choose one of them to be mandatory, but I am not satisfied with it since mandatory field is what I am trying to avoid.
目前的解决方案是任意选择其中一个是强制性的,但我不满意,因为强制性字段是我试图避免的。
Also, making an or does not suit me, since I would have to test groups when parsing the regex afterwards, instead of just accessing group(1) for days, group(2) for hours, ... (This is what I think of when speaking of an or : (?:([\d]+)d[\s]*(?:([\d]+)h)?[\s]*(?:([\d]+)m)?|(?:([\d]+)d)?[\s]*([\d]+)h[\s]*(?:([\d]+)m)?|(?:([\d]+)d)?[\s]*(?:([\d]+)h)?[\s]*([\d]+)m)
, to be understood as days mandatory or hours mandatory or minutes mandatory).
另外,制作一个或不适合我,因为我不得不在之后解析正则表达式时测试组,而不是仅仅访问组(1)几天,组(2)几个小时,...(这就是我的想法当谈到a或:(?:( [\ d] +)d [\ s] *(?:( [\ d] +)h)?[\ s] *(?:( [\ d] + )M)|(?:?([\ d] +)d)[\ S] *([\ d] +)H [\ S] *(:???([\ d] +)M)| (?:([\ d] +)d)?[\ s] *(?:( [\ d] +)h)?[\ s] *([\ d] +)m),理解为强制性的天数或强制性的小时数或必须的时间
So how could I modify my regex to make sure that at least one of my now-non-capturing group is not empty, be it days, hours or minutes?
那么我怎么能修改我的正则表达式以确保我现在非捕获组中的至少一个不是空的,无论是天,小时还是分钟?
2 个解决方案
#1
5
You can use a look-forward assert to ensure that at least one of d
h
or m
appears.
您可以使用前瞻断言来确保出现d h或m中的至少一个。
(?=.*[mhd])(?:(\d+)d)?\s*(?:(\d+)h)?\s*(?:(\d+)m)?
#2
2
As OmnipotentEntity suggested, you can use a positive look-ahead to determine if the number(s) are followed by a d
, m
or h
.
正如OmnipotentEntity建议的那样,您可以使用正向预测来确定数字是否后跟d,m或h。
Another way of writing it could be:
另一种写作方式可能是:
(\d+(?=[dhm])[dhm]\s*){1,3}
This would match the following:
这将符合以下内容:
4d 8h 42m
3d
15h
28m
12d 24m
2h 55m
7d 11h 24m
5d2h5m
#1
5
You can use a look-forward assert to ensure that at least one of d
h
or m
appears.
您可以使用前瞻断言来确保出现d h或m中的至少一个。
(?=.*[mhd])(?:(\d+)d)?\s*(?:(\d+)h)?\s*(?:(\d+)m)?
#2
2
As OmnipotentEntity suggested, you can use a positive look-ahead to determine if the number(s) are followed by a d
, m
or h
.
正如OmnipotentEntity建议的那样,您可以使用正向预测来确定数字是否后跟d,m或h。
Another way of writing it could be:
另一种写作方式可能是:
(\d+(?=[dhm])[dhm]\s*){1,3}
This would match the following:
这将符合以下内容:
4d 8h 42m
3d
15h
28m
12d 24m
2h 55m
7d 11h 24m
5d2h5m