如何使用正则表达式区分具有不同出现次数的相同模式?

时间:2016-12-31 16:19:53

标签: python regex bash grep

我想知道如何在不相等数量的行之间做出区分。 例如:

 100.00000     150.00000
 18.1170      998.00      575.31    -1318.75      575.31

预期的结果是返回第1行或第2行,但不是两者 表达式应该认识到第一行有两个浮点数,第二行由五个任意长度的浮点数组成,其间有任意数量的空格。

python(或其他)中的解决方案是分割行和计算列表的元素,但我想知道是否可以编写表达式来标识不同列数的行。

我试过\d+\.\d+但是当然这显然不会在不同列数的行之间产生差异。

我也试过这样的事情,(作为whitespace-number-whitespace-number mask):

^\s+[0-9]+\.[0-9]+\s+[0-9]+\.[0-9]+\s+[0-9]+\.[0-9]+

这也不是我想要的。

或使用群组(\d+\.[0-9]+\s)+

1 个答案:

答案 0 :(得分:1)

此正则表达式查找少于或多于5个值的行

^[\t ]*(?:(?:-?[\d.]+[\t ]*){0,4}|(?:-?[\d.]+[\t ]+){5}[-\d.].*)$

<强>解释

^ ...在一行的开头开始每次搜索。

[\t ]* ...在该行的开头匹配0个或多个制表符或空格。

这里使用\s并不好,因为这个字符类匹配任何包含换行符回车符和换行符的空格字符,搜索表达式永远不应该匹配跨越多行的字符串。

(?: ... | ... ) ...非捕获组中的OR表达式。

OR表达式的第一个参数用于查找0到4个值的行。

(?: ... ){0,4} ...圆括号内的表达式必须至少匹配0次,但不得超过4次。

-? ...匹配可选的现有连字符(用作减号)。

[\d.]+[\t ]* ...匹配任意数字或点1次或多次,然后是 0 或更多标签或空格。

OR表达式的第二个参数用于查找具有6个或更多值的行。

(?: ... ){5} ...圆括号内的表达式必须恰好匹配5次。

-? ...匹配可选的现有连字符(用作减号)。

[\d.]+[\t ]+ ...匹配任意数字或点1次或多次,然后是 1 或更多标签或空格。

[-\d.].* ...匹配连字符,任意数字或点以及 0 或更多字符,直到行尾。如果在5个值之后至少有1个其他值字符,则该行肯定包含多于5个值。

$ ...匹配的字符串必须以行尾(或文件末尾)结尾。

表达式也匹配行终止

以下扩展表达式也可用于匹配DOS / Windows类型的行终止(回车+换行)或UNIX(仅换行)或MAC(仅回车)应从文件中完全删除错误的值。

^[\t ]*(?:(?:-?[\d.]+[\t ]*){0,4}|(?:-?[\d.]+[\t ]+){5}[-\d.].*)$(?:\r?\n|\r)?

对于3种类型的行终止的非捕获OR表达式之后的问号导致也匹配文件的最后一行,如果该行没有行终止并且该文件末尾的该字符串不具有恰好5个浮点值。

查找具有5个浮点值的行:

为了完整性,找到恰好有5个值的行相反:

^[\t ]*(?:-?[\d.]+[\t ]+){4}-?[\d.]+[\t ]*$

或者也匹配行终止(或只是文件末尾的5个值):

^[\t ]*(?:-?[\d.]+[\t ]+){4}-?[\d.]+[\t ]*$(?:\r?\n|\r)?

但是,如果选项卡/空格分隔值文件包含例如

100.0000     150.0000
100.0000     150.0000    200.0000
 18.1170     998.00      575.31      -1318.75       575.31
-54.1270     -13.20        8.45         27.7564    9863.6246
 -2.84      7520.8843    -74.8305      340.4149     237.7302
935.224      738.720     942.9         270.0034       8.3053    2943.20

,任务是标记

  • 带有感叹号的每一行与下一行相比具有不同数量的浮点值

  • 带有等号,每行与相同数量的浮点值相比,下一行以及文件中的最后一行

在行的开头有一个额外的空格来获取输出

! 100.0000     150.0000
! 100.0000     150.0000    200.0000
=  18.1170     998.00      575.31      -1318.75       575.31
= -54.1270     -13.20        8.45         27.7564    9863.6246
!  -2.84      7520.8843    -74.8305      340.4149     237.7302
= 935.224      738.720     942.9         270.0034       8.3053    2943.20

只使用一个正则表达式,答案是:

这是不可能的。