gpt4 book ai didi

java - 如何在运行时生成正则表达式以匹配数值范围

转载 作者:行者123 更新时间:2023-11-29 09:39:58 25 4
gpt4 key购买 nike

我需要在运行时生成一个匹配一系列数值的正则表达式。

例如:在运行时我可能会发现我需要一个正则表达式来匹配“范围”a-261-b.somethinga-543-b 中的所有文件.something.

我需要生成一个匹配所有这些文件的正则表达式。有什么想法吗?

我需要它在 Java 中,所以如果有人知道任何特定于 Java 的方法,它也是可以接受的。

最佳答案

正则表达式是否适合这个任务是值得商榷的。大多数人可能会争辩说它不是。

然而,据我了解,您别无选择,因为您使用的 API 将正则表达式作为参数,所以这里...

代码

public class NumericRangeRegexGenerator {

private static String baseRange(String num, boolean up, boolean leading1) {

char c = num.charAt(0);
char low = up ? c : leading1 ? '1' : '0';
char high = up ? '9' : c;

if (num.length() == 1)
return charClass(low, high);

String re = c + "(" + baseRange(num.substring(1), up, false) + ")";

if (up) low++; else high--;

if (low <= high)
re += "|" + charClass(low, high) + nDigits(num.length() - 1);

return re;
}

private static String charClass(char b, char e) {
return String.format(b==e ? "%c" : e-b>1 ? "[%c-%c]" : "[%c%c]", b, e);
}

private static String nDigits(int n) {
return nDigits(n, n);
}

private static String nDigits(int n, int m) {
return "[0-9]" + String.format(n==m ? n==1 ? "":"{%d}":"{%d,%d}", n, m);
}

private static String eqLengths(String from, String to) {

char fc = from.charAt(0), tc = to.charAt(0);

if (from.length() == 1 && to.length() == 1)
return charClass(fc, tc);

if (fc == tc)
return fc + "("+rangeRegex(from.substring(1), to.substring(1))+")";

String re = fc + "(" + baseRange(from.substring(1), true, false) + ")|"
+ tc + "(" + baseRange(to.substring(1), false, false) + ")";

if (++fc <= --tc)
re += "|" + charClass(fc, tc) + nDigits(from.length() - 1);

return re;
}

private static String nonEqLengths(String from, String to) {
String re = baseRange(from,true,false) + "|" + baseRange(to,false,true);
if (to.length() - from.length() > 1)
re += "|[1-9]" + nDigits(from.length(), to.length() - 2);
return re;
}

public static String rangeRegex(int n, int m) {
return rangeRegex("" + n, "" + m);
}

public static String rangeRegex(String n, String m) {
return n.length() == m.length() ? eqLengths(n, m) : nonEqLengths(n, m);
}

}

用法

// Generate expression for range 123 - 321
String regexp = NumericRangeRegexGenerator.rangeRegex(123, 321);


解释

代码的简要说明如下。

0000-abcdabcd-9999

形状的范围

首先我们注意到匹配范围如 0000-abcd 是相当容易的。

例如000-527的表达式可以表示为

  • [0-4] 后跟两个任意数字,或者
  • 5 后跟 00-27(递归解析!)

形状 1000-abcdabcd-9999 的范围同样简单。

不同长度的下限、上限

如果“from”-number 比“to”-number 短,则非常简单。

假设 from 号码有 3 位,to 号码有 7 位。表达式可以组成如下:

  • from-999(如上所述),
  • 任何 456 数字:[1-9][0-9]{3-5 },或
  • 1000000-(如上所述)

等长的下限/上限。

这是最棘手的情况(虽然还不是棘手!)

再一次,解决方案最好用一个例子来描述。考虑范围 273 - 548。表达式可以由以下部分组成:

  • 2 后跟 73-99(后半部分如上所述),
  • [34] 后跟任意两位数,或
  • 5 后跟 00-48(后半部分如上所述)

关于java - 如何在运行时生成正则表达式以匹配数值范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6349161/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com