正则表达式匹配大多数显式字符串

时间:2015-07-01 17:34:25

标签: regex

我对正则表达式有一些经验,但我远非专家级别,需要一种方法来匹配记录与文件中最明确的字符串,其中每个记录以唯一的1-5位整数开头并填充各种短于5位的其他字符。例如,我的文件包含以:

开头的记录
32000
3201X
32014
320xy

在此示例中,非数字字符表示通配符。我认为以下正则表达式示例可以工作,但不是将记录与MOST显式数字匹配,它们总是将记录与LEAST显式数字匹配。记住,我不知道文件中有什么,所以我需要测试找到MOST显式匹配的所有可能性。

If I need to search for 32000, the regex looks something like:
    /^3\D{4}|^32\D{3}|^320\D{2}|^3200\D|^32000/
  It should match 32000 but it matches 320xy

If I need to search for 32014, the regex looks something like:
    /^3\D{4}|^32\D{3}|^320\D{2}|^3201\D|^32014/
  It should match 32014 but it matches 320xy

If I need to search for 32015, the regex looks something like:
    /^3\D{4}|^32\D{3}|^320\D{2}|^3201\D|^32015/
  It should match 3201x but it matches 320xy

在每种情况下,匹配结果都是LEAST特定数值。我还尝试通过以下方式反转正则表达式仍然得到相同的结果:     / ^ 32014 | ^ 3201 \ d | ^ 320 \ d {2} | ^ 32 \ d {3} | ^ 3 \ d {4} /

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

好的,如果你想按字面意思匹配字符串,那么使用锚点。然后指定要匹配的字符串。比如匹配' 123456xyz'其中xyz可以是除数字使用之外的任何东西:

'^123456[^0-9]{3}$'

如果你喜欢最后匹配的特定字母,如果它们总是x或z,那么使用:

'^123456[xyz]{3}$'

注意^和$将字符串锚定为以12345开头,并以三个字母x y或z结尾。

祝你好运!

答案 1 :(得分:0)

好的,我在这里做了很多修修补补。我99%肯定这几乎是不可能的(如果我们不欺骗和插入代码到正则表达式)。原因是你需要在某些时候使用可变长度的负面观察。

然而,我想出了两个选择。一个是如果你想要找到“最精确的匹配”,第二个是如果你想用某些东西替换它。我们走了:

/(32000)|\A(?!.*32000).*(3200\D)|\A(?!.*3200[0\D]).*(320\D\D)|\A(?!.*320[0\D][0\D]).*(32\D\D\D)|\A(?!.*32[0\D][0\D][0\D]).*(3\D\D\D\D)/m

问题:

  

那么我的“最精确匹配”是什么?

答案:

  

5个匹配组的串联 - \1\2\3\4\5。事实上,其中只有一个会匹配,其他4个将是空的。

/(32000)|\A(?!.*32000)(.*)(3200\D)|\A(?!.*3200[0\D])(.*)(320\D\D)|\A(?!.*320[0\D][0\D])(.*)(32\D\D\D)|\A(?!.*32[0\D][0\D][0\D])(.*)(3\D\D\D\D)/m

问题:

  

如何使用它来替换“最精确的匹配”?

答案:

  

在这种情况下,您的“最精确匹配”将是\1\3\5\7\9的串联,但在此之前我们也会匹配其他一些内容,即\2\4\6\8(同样,其中只有一个可以是非空的)。因此,如果您要将“最完全匹配”替换为fubar,则可以与上述正则表达式匹配,并替换为\2\4\6\8fubar

你可以考虑的另一种方式(并且可能有帮助)是你的“最精确匹配”将是两个正则表达式中任何一个的最后匹配行。

这里有两点需要注意:

  • 我使用Ruby样式RE,\A表示字符串的开头(不是行的开头 - ^)。 \m表示多行模式。您应该能够在语言/技术中找到相同内容的语法,只要它使用某种PCRE。
  • 这可能很慢。如果我们找不到完全匹配,我们可能需要匹配并替换整个字符串(如果可以在字符串的末尾找到非完全匹配)。