需求说明
如何求出一个正则表达式,表示在 1324736000 到 1546272000之间的正则表达式结果
例如
15423232231
这个根据正则表达式能够识别出来为true
代码结果
输入数据 为starttime 和 endtime(用户可以自己自定义时间格式,并转换为如下类型就行了)
input
def main(args: Array[String]): Unit = {
val starttime = "1324736000"
val endtime = "1546272000"
println(RegrexUtils.timeRangeRegrex(starttime,endtime))
}
output
1((3((2((4((7((3((6((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([7-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))|([4-8]\d{4})|(9((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))))|([8-8]\d{5})|(9((0((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))|([1-8]\d{4})|(9((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))))))|([5-8]\d{6})|(9((0((0((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))|([1-8]\d{4})|(9((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))))|([1-8]\d{5})|(9((0((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))|([1-8]\d{4})|(9((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))))))))|([3-8]\d{7})|(9((0((0((0((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))|([1-8]\d{4})|(9((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))))|([1-8]\d{5})|(9((0((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))|([1-8]\d{4})|(9((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))))))|([1-8]\d{6})|(9((0((0((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))|([1-8]\d{4})|(9((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))))|([1-8]\d{5})|(9((0((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))|([1-8]\d{4})|(9((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))))))))))|([4-4]\d{8})|(5((0((0((0((0((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))|([1-8]\d{4})|(9((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))))|([1-8]\d{5})|(9((0((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))|([1-8]\d{4})|(9((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))))))|([1-8]\d{6})|(9((0((0((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))|([1-8]\d{4})|(9((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))))|([1-8]\d{5})|(9((0((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))|([1-8]\d{4})|(9((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))))))))|([1-3]\d{7})|(4((0((0((0((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))|([1-8]\d{4})|(9((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))))|([1-8]\d{5})|(9((0((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))|([1-8]\d{4})|(9((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))))))|([1-5]\d{6})|(6((0((0((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))|([1-8]\d{4})|(9((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))))|([1-1]\d{5})|(2((0((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-8]\d{3})|(9((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))))|([1-6]\d{4})|(7((0((0((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))|([1-8]\d{2})|(9((0(([0-9])))|([1-8]\d{1})|(9(([0-9])))))))|([1-1]\d{3})|(2000))))))))))))
实际应用
这个需求是因为由于公司内部rowkey的设计导致的,
rowkey为 id+timestampe
如果想对整个表中的指定1324736000 到 1546272000范围内的数据进行聚合操作
其中一个解决方案是用rowkey的过滤方式进行大量计算合并
如何生成这样的一个模型或则通用地能解决这样的问题?
解题思路
生成策略使用分而治之与减而治之的基本套路,利用如上的输入来作为分析的起点,掌握特征。通过对输入数据的特征分析和结果。我们可以把正则表达式通过分段的方式来表达。这样就能够表达所有有关的
大体思路分三步走
1.1324736000 - 1399999999
2.14 + \d{8}
3. 1500000000 - 1546272000
代码(scala版本,读者可以根据自己的思路上)
object RegrexUtils {
def compute(start: String, end: String): Map[String, String] = {
val len = start.length
if(start == end) {
Map("prex" -> s"${start}","left" -> s"","middle" -> s"", "right"-> s"")
} else {
if(len == 1) {
Map("prex" -> "","left" -> s"${start}","middle" -> s"[${start}${end}]", "right"-> s"${end}")
} else {
// 算法从左中右三种算法实现
var prex = ""
var left = ""
var middle = "["
var right = ""
var equallen =0
// 提取前面重复的前缀
while(start(equallen) == end(equallen)) {
prex += start(equallen)
equallen += 1
}
val restlen = len - equallen
// 有没有两个数据一摸一样的?
if(equallen != len ) {
val startpoint = (start(equallen)+"").toInt
val endpoint =(end(equallen)+"").toInt
// 这两个点一定不相同
// 这里当间隔大于等于2个的时候
val leftstart = start.substring(equallen)
val rightend = end.substring(equallen)
var leftend = ""
var rightstart = ""
// 只有一个的时候
if(restlen == 1) {
middle += startpoint + "-" + endpoint + "]"
} else{
if(endpoint - startpoint > 1) {
middle+=s"${startpoint+1}-${endpoint-1}]\\d{${restlen - 1}}"
} else {
middle = ""
}
// 2. 计算左值
// 123456 19999
leftend = startpoint + "9" * (restlen - 1)
rightstart = endpoint + "0" * (restlen - 1)
val leftmap = compute(leftstart,leftend)
val rightmap = compute(rightstart, rightend)
left += formatResult(leftmap)
right += formatResult(rightmap)
}
} else {
prex = start
}
// val regx = prex + "("+ left + "|" + middle + "|" + right + ")"
Map("prex" -> prex,"left" -> left,"middle" -> middle, "right" -> right)
}
}
}
def formatResult(map: Map[String,String])= {
val leftstring = {
if(s"${map.getOrElse("left","")}"!="") {
s"(${map.getOrElse("left","")})|"
} else {
""
}
}
val middlestring = {
if(s"${map.getOrElse("middle","")}"!="") {
s"(${map.getOrElse("middle","")})|"
} else {
""
}
}
val rightstring = {
if(s"${map.getOrElse("right","")}"!="") {
s"(${map.getOrElse("right","")})"
} else {
""
}
}
var tuple = s"${leftstring}${middlestring}${rightstring}"
if(tuple.endsWith("|")){
tuple = tuple.substring(0,tuple.length-1)
}
if(tuple == "") {
s"${map.getOrElse("prex","")}"
} else {
s"${map.getOrElse("prex","")}(${tuple})"
}
}
def timeRangeRegrex(starttime: String, endtime: String):String = {
val startlen = starttime.length
val endlen = endtime.length
var maxlen = startlen
if(maxlen < endlen) {
maxlen = endlen
}
val newstarttime: String = String.format(s"%0${maxlen}d",java.lang.Long.valueOf(starttime))
val newendtime: String = String.format(s"%0${maxlen}d",java.lang.Long.valueOf(endtime.toLong))
formatResult(compute(newstarttime,newendtime))
}
def main(args: Array[String]): Unit = {
// val starttime = "1324736000"
// val endtime = "1546272000"
val starttime = "1"
val endtime = "52"
// val data = compute(starttime,endtime)
println(RegrexUtils.timeRangeRegrex(starttime,endtime))
}
}
如何进行单元测试脚本
当写好各种脚本之后,需要测试正则表达式功能是否完备
def main(args: Array[String]): Unit = {
val starttime = "1324736000"
val endtime = "1546272000"
val regrex = RegrexUtils.timeRangeRegrex(starttime,endtime)
println(regrex)
val pattern = Pattern.compile(regrex)
for(a <- starttime.toLong until (endtime.toLong+1)){
val str = "%010d".format(a)
val matcher = pattern.matcher(str)
val find = matcher.find()
if(!find){
println(str)
}
assert(find);
}
}
代码地址
查看地址
如有纰漏,不吝赐教