当前位置: 首页 > 面试题库 >

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

弘柏
2023-03-14
问题内容

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

例如:在运行时,我可能会发现我需要一个正则表达式,将“范围”中的所有文件都匹配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有3位数字,to-number有7位数字。表达式可以组成如下:

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

等长的下限/上限。

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

同样,该解决方案最好通过一个示例来描述。考虑范围273- 548。该表达式可以由以下部分组成:

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


 类似资料:
  • 问题内容: 是的,您没看错。我需要能够从正则表达式 生成 随机文本的内容。因此,文本应该是随机的,但要与正则表达式匹配。看来它不存在,但我可能是错的。 仅举一个例子:该库将能够以“ ”作为输入,并生成诸如以下示例: abc abbbc bac 等等 更新:我自己创建了一些东西:Xeger。查看http://code.google.com/p/xeger/。 问题答案: 我刚刚创建了一个库来进行此操

  • 正则表达式如何匹配出这个字符串'calc(100vh - 420px)'中的数字420

  • 问题内容: 我正在使用模块中的函数来匹配某些东西,并且一切正常。 现在,我需要找出我有多少场比赛。是否可以不两次遍历迭代器?(先找出计数然后是真正的迭代) 一些代码: 一切正常,我只需要在循环之前获取匹配数即可。 问题答案: 如果您知道需要所有匹配项,则可以使用该功能。它将返回所有匹配项的列表。然后,您可以只进行匹配次数。

  • 问题内容: 什么正则表达式将匹配Java中的任何ASCII字符? 我已经尝试过: 但是发现它与我想要的很多东西都不匹配(例如空格,括号等)。我希望避免以如下格式显式列出所有127个ASCII字符: 问题答案: 我没用过但是我用过

  • 我们得到了一些这样的内容:

  • 说到正则表达式,我没那么令人印象深刻。。。 我试图匹配一个单词中除第二个字符外的所有字符。 我想匹配 示例字符串: 我提出了以下两个正则表达式。 除第一个字符外,此字符与“uml”匹配( -- 这与第一个字符匹配,除了最后3个(uml)