如何优化正则表达式模式?
How to optimize a regex pattern?
我正在尝试从文本中获取子字符串并使用正则表达式。
示例文本:
bla bla 1:30-2pm bla bla 5-6:30am some text 1-2:15am
我正在寻找时间范围条目(1-30-2pm...)。将它们加粗只是为了便于阅读
这是我的正则表达式:
\d{1,2}(:\d{1,2})? – \d{1,2}(:\d{1,2})?(am|pm)
java 片段:
public static List<String> foo(String text, String regex) {
List<String> entries = new ArrayList<>();
Matcher matcher = Pattern.compile(regex).matcher(text);
while (matcher.find()) {
entries.add(matcher.group());
}
return entries;
}
你能帮我优化正则表达式模式吗?可能有一些我错过的用例。
我建议使用像
这样的正则表达式
String regex = "(?i)(?<!\d)(?:0?[1-9]|1[0-2])(?::[0-5]\d)?\p{Pd}(?:0?[1-9]|1[0-2])(?::[0-5]\d)?[ap]m\b";
详情
(?i)
- 不区分大小写的标志(对于 AM
、PM
、am
、pm
值等)
(?<!\d)
- 不允许紧靠左边的数字
(?:0?[1-9]|1[0-2])
- 一个可选的 0
,然后是从 1
到 9
的数字,或者 1
然后是 0
,1
或 2
(?::[0-5]\d)?
- 可选组:从 0
到 5
的数字,然后是任何一个数字
\p{Pd}
- 任何连字符
(?:0?[1-9]|1[0-2])(?::[0-5]\d)?
- 见上文
[ap]m\b
- a
或 p
然后是 m
和单词边界。
如果我们想优化我们的表达式,我们可能想要添加可选空格,以防我们的输入可能有任何额外的空格,除此之外,您的表达式看起来很棒:
(\d{1,2})(:\d{1,2})?(\s+)?-(\s+)?(\d{1,2})(:\d{1,2})?(am|pm)
如果我们想获取数据,我们还添加了捕获组。
Demo 1
或者:
(\d{1,2})(:\d{1,2})?(\s+)?(am|pm)?(\s+)?-(\s+)?(\d{1,2})(:\d{1,2})?(\s+)?(am|pm)
Demo 2
无论你想要哪个。
测试
import java.util.regex.Matcher;
import java.util.regex.Pattern;
final String regex = "(\d{1,2})(:\d{1,2})?(\s+)?-(\s+)?(\d{1,2})(:\d{1,2})?(am|pm)";
final String string = "bla bla 1:30-2pm bla bla 5-6:30am some text 1-2:15am\n"
+ "bla bla 1:30 - 2pm bla bla 5 - 6:30am some text 1 - 2:15am";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
final Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
for (int i = 1; i <= matcher.groupCount(); i++) {
System.out.println("Group " + i + ": " + matcher.group(i));
}
}
正则表达式
如果不需要此表达式并且您希望对其进行修改,请访问此 link regex101.com。
正则表达式电路
jex.im 可视化正则表达式:
我正在尝试从文本中获取子字符串并使用正则表达式。 示例文本:
bla bla 1:30-2pm bla bla 5-6:30am some text 1-2:15am
我正在寻找时间范围条目(1-30-2pm...)。将它们加粗只是为了便于阅读
这是我的正则表达式:
\d{1,2}(:\d{1,2})? – \d{1,2}(:\d{1,2})?(am|pm)
java 片段:
public static List<String> foo(String text, String regex) {
List<String> entries = new ArrayList<>();
Matcher matcher = Pattern.compile(regex).matcher(text);
while (matcher.find()) {
entries.add(matcher.group());
}
return entries;
}
你能帮我优化正则表达式模式吗?可能有一些我错过的用例。
我建议使用像
这样的正则表达式String regex = "(?i)(?<!\d)(?:0?[1-9]|1[0-2])(?::[0-5]\d)?\p{Pd}(?:0?[1-9]|1[0-2])(?::[0-5]\d)?[ap]m\b";
详情
(?i)
- 不区分大小写的标志(对于AM
、PM
、am
、pm
值等)(?<!\d)
- 不允许紧靠左边的数字(?:0?[1-9]|1[0-2])
- 一个可选的0
,然后是从1
到9
的数字,或者1
然后是0
,1
或2
(?::[0-5]\d)?
- 可选组:从0
到5
的数字,然后是任何一个数字\p{Pd}
- 任何连字符(?:0?[1-9]|1[0-2])(?::[0-5]\d)?
- 见上文[ap]m\b
-a
或p
然后是m
和单词边界。
如果我们想优化我们的表达式,我们可能想要添加可选空格,以防我们的输入可能有任何额外的空格,除此之外,您的表达式看起来很棒:
(\d{1,2})(:\d{1,2})?(\s+)?-(\s+)?(\d{1,2})(:\d{1,2})?(am|pm)
如果我们想获取数据,我们还添加了捕获组。
Demo 1
或者:
(\d{1,2})(:\d{1,2})?(\s+)?(am|pm)?(\s+)?-(\s+)?(\d{1,2})(:\d{1,2})?(\s+)?(am|pm)
Demo 2
无论你想要哪个。
测试
import java.util.regex.Matcher;
import java.util.regex.Pattern;
final String regex = "(\d{1,2})(:\d{1,2})?(\s+)?-(\s+)?(\d{1,2})(:\d{1,2})?(am|pm)";
final String string = "bla bla 1:30-2pm bla bla 5-6:30am some text 1-2:15am\n"
+ "bla bla 1:30 - 2pm bla bla 5 - 6:30am some text 1 - 2:15am";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
final Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
for (int i = 1; i <= matcher.groupCount(); i++) {
System.out.println("Group " + i + ": " + matcher.group(i));
}
}
正则表达式
如果不需要此表达式并且您希望对其进行修改,请访问此 link regex101.com。
正则表达式电路
jex.im 可视化正则表达式: