【问题标题】:How to differentiate between same pattern with different number of occurrences using regex?如何使用正则表达式区分出现次数不同的相同模式?
【发布时间】:2016-12-31 16:19:53
【问题描述】:

我想知道如何区分列数不等的行。 例如:

 100.00000     150.00000
 18.1170      998.00      575.31    -1318.75      575.31

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

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

我试过\d+\.\d+ 但当然这显然不会对不同列数的行产生影响。

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

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

这也不是我想要的。

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

【问题讨论】:

  • 你为什么强迫你的想法使用正则表达式?我认为你不会比len(split(line))做得更好
  • @PaulMcGuire - 我在问题中写道,我有这样的解决方案,并且我对正则表达式方式感兴趣,如果有的话。好奇有错吗?
  • @EdMorton 我对正则表达式感兴趣,如果有任何解决这个问题的方法。这些行来自一个随机文件,是否有前两行并不重要。我认为很清楚,我想知道正则表达式是否可以区分第 1 行和第 2 行与第 3 行和第 4 行。
  • 我也想知道为什么投反对票?问题的哪些方面没有得到满足?
  • @EdMorton - 谢谢 Ed,我试图简化问题,希望它更清楚。一个“是”的答案很好,但它可能没有用:)

标签: python regex bash grep


【解决方案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)?

如果该行没有行终止符并且文件末尾的该字符串不完全是 5 个浮点值,则 3 种类型的行终止符的非捕获 OR 表达式后的问号也会匹配文件的最后一行。

查找正好有 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

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

这是不可能的。

【讨论】:

  • 感谢@Mofi 的详尽回答和结束语。 ^[\t ]*(?:-?[\d.]+[\t ]+){2,}-?[\d.]+[\t]*$ 将匹配我示例的第二行(超过两个浮点数)regex101.com/r/GQHsQu/2
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多