试图在单词边界之外匹配零

时间:2019-03-28 17:37:33

标签: regex

我有类似
的图案 FQC19515_TCELL001_20190319_165944.pdf
FQC19515_TBNK001_20190319_165944.pdf
我可以使用RegEX匹配单词TCELL和TBNK
^(\ D +)-(\ d +)-(\ d +)([[A-Z1-9] +)??。*

但是如果我有像
这样的模式 FLW194640_ T20NK 022_20190323_131348.pdf
FLW194228_ C1920 _SOME_DEBRIS_REMOVED.pdf
上面的正则表达式返回
T2和C192分别代替T20NK和C1920

是否有一个通用的正则表达式可以匹配这些单词边界之外的Nzeros?

2 个答案:

答案 0 :(得分:0)

让我们考虑一下您输入的所有4个示例:

FQC19515_TCELL001_20190319_165944.pdf
FQC19515_TBNK001_20190319_165944.pdf
FLW194640_T20NK022_20190323_131348.pdf
FLW194228_C1920_SOME_DEBRIS_REMOVED.pdf

第一个组,位于行首和第一个“ _”之间(例如,第1行中的FQC19515) 包含:

  • 一个非空字母序列,
  • 非空数字序列。

因此匹配它的正则表达式,包括行锚的开始和捕获组为:

^([A-Z]+\d+)

您使用的是\D而不是[A-Z],但我认为[A-Z]是 更具体,因为它与仅字母匹配,而不与“ _”。

下一个源字符为_,因此正则表达式也可以包含_

现在是更重要的部分:要捕获的第二组有 实际上有2种变体:

  • 一个字母序列和一个数字序列(之后是 一个“ _”),
  • 一个字母序列,一个数字序列和另一个 字母(此后您要省略数字)。

因此,最直观的方法是定义2个替代方案,每个替代方案 相应的正向提前

  • 替代方法1:[A-Z]+\d+(?=_)
  • 替代2:[A-Z]+\d+[A-Z]+(?=\d)

但是有一种更短的方法。请注意,两种选择都开始 来自[A-Z]+\d+。 因此,我们可以将此片段放在第一位,而仅将其余部分 包括为非捕获组((?:...)),并有2种选择。 以上所有内容都应包含一个捕获组

([A-Z]+\d+(?:(?=_)|[A-Z]+(?=\d)))

因此整个正则表达式可以是:

^([A-Z]+\d+)_([A-Z]+\d+(?:(?=_)|[A-Z]+(?=\d)))

带有m选项(“ ^”也匹配每行的开头)。

有关工作示例,请参见https://regex101.com/r/GDdt10/1

您的正则表达式:^(\D+)-(\d+)错误,因为出现了一系列非数字 (\D+)您指定了一个,它不会出现在您的来源中。 另外,第二个减号也与您的输入不符。

编辑

为匹配所有您的字符串,我对先前的正则表达式进行了一些修改。 更改仅限于匹配组2(在_之后):

  • 替代项1:[A-Z]{2,}+(?=\d)-在它们之后的两个或多个字母 有一个数字,可以省略。它将匹配TCELLTBNK
  • 替代2:[A-Z]+\d+(?:(?=_)|[A-Z]+(?=\d))-前一个 该组的内容。它将匹配其余两个案例。

所以整个正则表达式是:

^([A-Z]+\d+)_([A-Z]{2,}+(?=\d)|[A-Z]+\d+(?:(?=_)|[A-Z]+(?=\d)))

有关工作示例,请参见https://regex101.com/r/GDdt10/2

答案 1 :(得分:0)

据我了解,您可以使用:

^[A-Z]+\d+_\K[A-Z0-9]{5}

说明:

^                   # beginning of line
    [A-Z]+          # 1 or more capitals
    \d+_            # 1 or more digit and 1 underscore
    \K              # forget all we have seen until this position
    [A-Z0-9]{5}     # 5 capitals or digits

Demo