使用Regex生成字符串而不是匹配它们

时间:2020-03-05 18:41:57  来源:igfitidea点击:

我正在编写一个Java实用程序,可以帮助我生成大量数据以进行性能测试。能够为Strings指定一个正则表达式真的很酷,这样我的生成器就会吐出与此匹配的东西。有没有已经烤好的东西可以用来做呢?还是有一个图书馆可以带给我大部分帮助?

谢谢

解决方案

回答

我们必须编写自己的解析器,就像String :: Random(Perl)的作者一样。实际上,他在该模块中的任何地方都没有使用正则表达式,而这正是perl编码器所习惯的。

另一方面,也许我们可​​以看一下源代码,以获得一些指针。

编辑:该死,布莱尔以15秒击败了我一拳。

回答

编辑:

如评论中所述,Google Code提供了一个可实现此目的的库:
http://code.google.com/p/xeger

另请参阅Mifmif建议的https://github.com/mifmif/Generex

原始信息:

首先,我相信使用足够复杂的正则表达式,这是不可能的。但是我们应该能够将一些东西放在一起进行简单的正则表达式。

如果查看类java.util.regex.Pattern的源代码,我们会发现它使用Node实例的内部表示形式。每个不同的模式组件都有自己的Node子类实现。这些节点被组织成一棵树。

通过产生遍历此树的访问者,我们应该能够调用重载的生成器方法或者某种将某些东西拼凑在一起的Builder。

回答

Visual Studio Team System确实包含这样的内容。一探究竟

虽然对Java没有太多帮助,所以很抱歉。

回答

在stackoverflow播客11上:

Spolsky:  Yep.  There's a new product also, if you don't want to use the Team System there our friends at Redgate have a product called SQL Data Generator [http://www.red-gate.com/products/sql_data_generator/index.htm].  It's 5, and it just generates some realistic test data.  And it does things like actually generate real cities in the city column that actually exist, and then when it generates those it'll get the state right, instead of getting the state wrong, or putting states into German cities and stuff like... you know, it generates pretty realistic looking data.  I'm not really sure what all the features are.

这可能不是我们想要的,但它可能是一个不错的起点,而不是创建自己的起点。

我似乎在google中找不到任何内容,因此建议通过将给定的正则表达式解析为最小的工作单位(\ w,[xx],\ d等)并编写一些基本方法来解决该问题那些正则表达式短语。

因此,对于\ w,我们将有一个方法getRandomLetter()返回任意随机字母,并且我们还将有getRandomLetter(char startLetter,char endLetter)为我们提供两个值之间的随机字母。

回答

我知道已经有一个可以接受的答案,但是我一直在使用RedGate的数据生成器(在Craig的答案中提到的那个),并且对于我投入的所有内容,它都非常有效。它的速度很快,而我却想使用相同的正则表达式来生成诸如此类的注册码之类的真实数据。

它需要一个正则表达式,例如:

[A-Z0-9]{3,3}-[A-Z0-9]{3,3}

并生成大量独特的代码,例如:

LLK-32U

这是RedGate想出的一个大秘密算法,我们都走运了吗,还是我们凡人实际上可以做的事情?

回答

它远不支持完整的PCRE正则表达式,但我编写了以下Ruby方法来获取类似regexp的字符串并对其产生变体。 (对于基于语言的验证码。)

# q = "(How (much|many)|What) is (the (value|result) of)? :num1 :op :num2?"
# values = { :num1=>42, :op=>"plus", :num2=>17 }
# 4.times{ puts q.variation( values ) }
# => What is 42 plus 17?
# => How many is the result of 42 plus 17?
# => What is the result of 42 plus 17?
# => How much is the value of 42 plus 17?
class String
  def variation( values={} )
    out = self.dup
    while out.gsub!( /\(([^())?]+)\)(\?)?/ ){
      (  && ( rand > 0.5 ) ) ? '' : .split( '|' ).random
    }; end
    out.gsub!( /:(#{values.keys.join('|')})\b/ ){ values[.intern] }
    out.gsub!( /\s{2,}/, ' ' )
    out
  end
end

class Array
  def random
    self[ rand( self.length ) ]
  end
end

回答

为此,我已经扎根了自己的库的根源(对于Java开发人员来说,cbut应该很容易理解)。

Rxrdg最初是为为实际项目创建测试数据的问题提供的解决方案。基本思想是利用现有(正则表达式)验证模式来创建符合此类模式的随机数据。这样,可以创建有效的随机数据。

为简单的正则表达式模式编写解析器并不难。使用抽象语法树生成字符串应该更加容易。

回答

Xeger(Java)也可以做到这一点:

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