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

如何在运行时生成正则表达式以匹配数字范围,第1张

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

正则表达式是否非常适合此任务尚待商.。大多数人可能会争论并非如此。

但是据我所知,您别无选择,因为您使用的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 - 321String regexp = NumericRangeRegexGenerator.rangeRegex(123, 321);
说明

代码的简要说明如下。

形状范围
0000
-
abcd
abcd
-
9999

首先,我们注意到匹配范围(例如

0000
-
abcd
)相当容易。

例如,一个表达式涵盖

000
-
527
可以表示为

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

形状的范围

1000
-
abcd
abcd
-
9999
一样容易。

下限,不同长度的上限。

如果“从”号比“到”号短,那是相当简单的。

例如,假设

from
-number有3位数字,
to
-number有7位数字。表达式可以组成如下:

  • from
    -
    999
    (如上所述),
  • 任何
    4
    5
    6
    位数:
    [1-9][0-9]{3-5}
  • 1000000
    -
    to
    (如上所述)
等长的下限/上限。

这是最棘手的情况(尽管仍然不是 那么 棘手!)

同样,该解决方案最好通过一个示例来描述。考虑范围

273
-
548
。该表达式可以由以下部分组成:

  • 2
    随后是
    73
    -
    99
    (上述部分),
  • [34]
    后跟任意两位数字,或者
  • 5
    后跟
    00
    -
    48
    (上述部分)


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5560676.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-14
下一篇 2022-12-14

发表评论

登录后才能评论

评论列表(0条)

保存