【问题标题】:How do I generate text matching a regular expression from a regular expression?如何从正则表达式生成与正则表达式匹配的文本?
【发布时间】:2010-12-07 10:03:52
【问题描述】:

是的,你没看错。我需要能够从正则表达式生成随机文本的东西。所以文本应该是随机的,但要通过正则表达式匹配。它似乎不存在,但我可能是错的。

只是一个例子:该库将能够将“[ab]*c”作为输入,并生成如下示例:

ABC
abbbc
后退

等等

更新:我自己创造了一些东西:Xeger。查看http://code.google.com/p/xeger/

【问题讨论】:

  • 好主意 - 有兴趣听听结果。
  • 这确实很有用!
  • 我认为任何“...或更多”选择器都必须受到限制,否则您最终可能会得到 1,000,000 个字符的单词:S
  • 你知道猴子会写莎士比亚的说法(无限猴子定理)......快速而肮脏的解决方案:生成随机字符串,直到你有一个匹配。这可能需要一段时间:-)。不过我希望看到一个真实的回复。
  • 这听起来可能是一个有趣的小项目。

标签: java regex random data-generation


【解决方案1】:

我不知道有这样的图书馆。如果您有兴趣自己编写一个,那么您可能需要采取以下步骤:

  1. 为正则表达式编写解析器(您可能希望从受限的正则表达式类开始)。

  2. 使用结果构造一个NFA

  3. (可选)将 NFA 转换为 DFA

  4. 将生成的自动机从开始状态随机遍历到任何接受状态,同时存储每次转换输出的字符。

结果是一个被原始正则表达式接受的单词。有关更多信息,请参见例如Converting a Regular Expression into a Deterministic Finite Automaton.

【讨论】:

  • 我一直在寻找可以从 Java 中的正则表达式创建 NFA 的库。我知道上面的方法会起作用,因为我很久以前就在 Javascript 中这样做过。
  • 我想这值得一看:brics.dk/~amoeller/automaton
  • 我基于上面提到的库实现了Xeger。
【解决方案2】:

Here'sa fewimplementations 这样的野兽,但它们都不是 Java 中的(除了封闭源代码的 Microsoft 之外,它们的正则表达式功能支持非常有限)。

【讨论】:

    【解决方案3】:

    我刚刚创建了一个库来执行此操作。它托管在这里:http://code.google.com/p/xeger/。使用前请仔细阅读说明。 (尤其是指下载另一个所需的库。);-)

    这是你使用它的方式:

    String regex = "[ab]{4,6}c";
    Xeger generator = new Xeger(regex);
    String result = generator.generate();
    assert result.matches(regex);
    

    【讨论】:

      【解决方案4】:

      这是一个类似模块的 Python 实现:http://www.mail-archive.com/python-list@python.org/msg125198.html 它应该可以移植到 Java。

      【讨论】:

        【解决方案5】:

        基于 Wilfred Springer 的解决方案以及 http://www.brics.dk/~amoeller/automaton/ 我构建了另一个生成器。 它不使用递归。它将模式/regularExpression 最小字符串长度和最大字符串长度作为输入。结果是最小和最大长度之间的可接受字符串。它还允许一些 XML“速记字符类”。 我将它用于为构面构建有效字符串的 XML 示例生成器。

        public static final String generate(final String pattern, final int minLength, final int maxLength) {
            final String regex = pattern
                    .replace("\\d", "[0-9]")        // Used d=Digit
                    .replace("\\w", "[A-Za-z0-9_]") // Used d=Word
                    .replace("\\s", "[ \t\r\n]");   // Used s="White"Space
            final Automaton automaton = new RegExp(regex).toAutomaton();
            final Random random = new Random(System.nanoTime());
            final List<String> validLength = new LinkedList<>();
            int len = 0;
            final StringBuilder builder = new StringBuilder();
            State state = automaton.getInitialState();
            Transition[] transitions;
            while(len <= maxLength && (transitions = state.getSortedTransitionArray(true)).length != 0) {
                final int option = random.nextInt(transitions.length);
                if (state.isAccept() && len >= minLength && len <= maxLength) validLength.add(builder.toString());
                final Transition t = transitions[option]; // random transition
                builder.append((char) (t.getMin()+random.nextInt(t.getMax()-t.getMin()+1))); len ++;
                state = t.getDest();
            }
            if(validLength.size() == 0) throw new IllegalArgumentException(automaton.toString()+" , "+minLength+" , "+maxLength);
            return validLength.get(random.nextInt(validLength.size()));
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-01-16
          相关资源
          最近更新 更多