基于输入创建正则表达式

时间:2012-05-22 13:31:50

标签: php javascript regex

我有一个用PHP编写的Web应用程序,它包含Javascript和JQuery,将用作我公司的库存管理系统(IMS)。我希望能够创建的是基于用户输入值的Regex表达式。

这背后的想法是,大多数制造商的序列号架构,字符长度以及字母与数字值的混合,对于某个部分是唯一的。因此,当一个部件被添加到IMS并且第一个序列号被扫描到系统中时,我希望构建一个Regex语句并将其保存到与该部件类型相对应的数据库表中。在将来扫描序列号时,应自动选择零件作为零件类型,因为它与该制造商的序列号架构相匹配。我理解这种方法可能并不总是适用于单个部分,因此我甚至可以返回与模式匹配的部分列表,而不是需要在目录中查找的部分。

我的问题的基础是,在代码中使用函数来解密用户创建的Regex表达式的值时,最好的起点是什么?我不是要求一个完整的功能,而是一个如何查看我的情况和目标的起点,以便我可以理解从哪里开始。我已经抓了很长时间,开始多次写功能只是为了删除整个区块,因为我知道自己要走向灾难。

代码中的任何内容都是可能的 - 这是可行的吗?


编辑 - 添加示例值

DVD-RW(光驱)

  • 1613518L121
  • 1613509L121
  • 1613519L121

VGA输出卡

  • 0324311071068
  • 0324311071134

COM扩展卡

  • 608131234
  • 608131237

硬盘

  • WMAYUJ753738
  • WMAYUJ072099
  • WMAYUJ683739
  • WMAYUJ844900

正如您所看到的,某些值只是一定长度的字符数。其他人在开头会有字母字符,然后是一系列数字。其他人可能有相互穿插的字母/数字字符。在大多数情况下,一个简单的字母/数字规则长度适合于识别我们的商品清单中的单一部分类型。但是,在多个表达式与值匹配的情况下,我可以简单地让应用程序显示与正则表达式匹配的两个或更多产品的列表,并提示用户选择正确的部分。总的来说,这将节省在WMS数据库中选择产品类型的时间和错误。

感谢您的评论。我知道我不会问一个有一个答案的问题。我正在寻找一个关于如何最好地逐步执行字符串并吐出与该值匹配的相应Regex语句的起点。

3 个答案:

答案 0 :(得分:2)

正如@Pete所说,我认为你已经为自己设定了过于雄心勃勃的目标。一些想法,或许可以从你的特定需求中过度推广。

我认为您要扫描序列号如1-56592-487-8并推断正则表达式/ \ d- \ d {5} - \ d {3} - \ d /匹配部分这种类型来自给定的制造商。 (这恰好是我的“果壳中的Java”的ISBN-10。“ISBN不是序列号,而是与我一起工作。”但是你不能从少数例子中推断出制造商使用的模式。也许第一个字符位置是十六进制数字(0-F)。也许最后一个字符是校验和,可以是数字或X(如ISBN)。也许有一个后缀,并不总是存在,表示植物。因此,您会发现自己为同一制造商/零件类型构建了许多模式,因为该零件的新实例会进入。

你也会遇到相反的问题。小工具制造商使用正则表达式/ [A-Z] {3} \ d {7} /,而声波螺丝刀制造商使用相同的模式。

那就是说,关于你能做的最好的事情是:

for each character in the scanned serial number
    if it is a capital letter
        add [A-Z] to the regular expression
    else if it is a digit
        add \d to the regular expression
    else 
        add the character itself to the regular expression, escaped as necessary
 end for
 collapse multiple occurrences with the {,} interval qualifier

Vehicle Identification Numbers的规则也可能令人振奋。考虑一些例子,考虑如何推断VIN的规则。

答案 1 :(得分:0)

编辑:对不起,我的示例代码有问题,您需要这种算法作为您猜测的部分的第一步:longest substringthis

你将需要添加iteratives和一些掩蔽像上面和由David解释,还对下面的示例中,“L121”为DVD-RW不猜测(如我已经指出,我必须得到起始“共同” )。因此,您需要找到所有常见的连续子序列,并确定哪些是相关的! (可能具有一种最大化增益函数)

使用第二个链接long_substr:

>>> for x in d:
    for y in d:
        if x == y: continue
        common = long_substr([x, y])
        length = len(common)
        if x.startswith(common) and y.startswith(common):
            print "\t".join((x, y, str(length), common))

产生=>

0324311071068   0324311071134   10  0324311071
0324311071134   0324311071068   10  0324311071
1613519L121 1613518L121 6   161351
1613519L121 1613509L121 5   16135
WMAYUJ844900    WMAYUJ753738    6   WMAYUJ
WMAYUJ844900    WMAYUJ072099    6   WMAYUJ
WMAYUJ844900    WMAYUJ683739    6   WMAYUJ
WMAYUJ753738    WMAYUJ844900    6   WMAYUJ
WMAYUJ753738    WMAYUJ072099    6   WMAYUJ
WMAYUJ753738    WMAYUJ683739    6   WMAYUJ
1613518L121 1613519L121 6   161351
1613518L121 1613509L121 5   16135
WMAYUJ072099    WMAYUJ844900    6   WMAYUJ
WMAYUJ072099    WMAYUJ753738    6   WMAYUJ
WMAYUJ072099    WMAYUJ683739    6   WMAYUJ
WMAYUJ683739    WMAYUJ844900    6   WMAYUJ
WMAYUJ683739    WMAYUJ753738    6   WMAYUJ
WMAYUJ683739    WMAYUJ072099    6   WMAYUJ
608131237   608131234   8   60813123
1613509L121 1613519L121 5   16135
1613509L121 1613518L121 5   16135
608131234   608131237   8   60813123

---第一辆越野车回复从这里开始

下面是我的回复的第一部分,它只能帮助您了解我的错误,并可能会给您一些想法:

根据您的特殊需要使用最长公共子序列问题求解器LCS的示例,我可以认为这是猜测什么是常见的过程的第一步?

它是在Python,但对于演示的一部分,它可以容易地可读的(或可被切割并在IDLE(蟒编辑器)中)assumong您使用第一连杆的ActiveState的代码食谱上述

这与生物信息学有关(想想基因排列)

你需要一些东西来决定什么是最有趣的常见序列(可能有一个最小的长度?然后像大卫已经提出的或在我的评论中进行掩蔽

(起初我不明白的是,LCS什么不是LCS连续求解器,而你会需要它!所以我的LCS求解器的第一次使用是马车:(因为它是不连续的,我有MAYUJ8或WMAYUJ7而不是WMAYUJ - 这是更短的!虽然求解者找到最长的常见字符而不期待它们是连续性的! - 再次抱歉)

>>> raw = """1613518L121
1613509L121
1613519L121

0324311071068
0324311071134

608131234
608131237

WMAYUJ753738
WMAYUJ072099
WMAYUJ683739
WMAYUJ844900"""
>>> d = dict()
>>> for line in raw.split("\n"):
    if not line.strip(): continue
    value = line.strip()
    d[value] = 1

>>> for x in d:
    for y in d:
        if x == y: continue
        length = LCSLength(x, y)
        common = LCS(x,y)
        if  length >= 3 and x.startswith(common):
            print "\t".join((x, y, str(length), common))

产生=>

0324311071068   0324311071134   10  0324311071
0324311071068   608131234   4   0324
0324311071134   0324311071068   10  0324311071
WMAYUJ844900    WMAYUJ753738    7   WMAYUJ8
WMAYUJ753738    WMAYUJ072099    7   WMAYUJ7
608131237   608131234   8   60813123
608131234   608131237   8   60813123

答案 2 :(得分:-1)

运行垃圾邮件检测算法(统计类似于贝叶斯或类似的“学习”算法)。这对你有帮助,但如果没有,我真的怀疑你会在这里做出任何有用的逻辑算法。