Группа захвата совпадений с регулярным выражением n раз - PullRequest
0 голосов
/ 01 апреля 2020

Ищем способ сопоставить шаблон ровно n раз. Например, следующий шаблон соответствует строке 's4':

s4='123.45    67.891  0.234   5678.90'
re.match(r'\s*\d+\.\d*',s4)
Out[167]: <re.Match object; span=(0, 6), match='123.45'>

Но он также будет соответствовать строкам 's3' и 's5':

s3='123.45    67.891  0.234'
s5='123.45    67.891  0.234   5678.90     12.34'

Как соответствовать только когда шаблон повторяется ровно 4 раза? "Точное совпадение" {4} жадный или {4}? Ленивец не будет соответствовать 's3', но все равно будет соответствовать 's5' и поместит 4-е вхождение в первую группу захвата:

re.match(r'(\s*\d+\.\d*){4}',s5)
Out[165]: <re.Match object; span=(0, 33), match='123.45    67.891  0.234   5678.90'>

re.match(r'(\s*\d+\.\d*){4}',s5).group(1)
Out[166]: '   5678.90'

Не понимает регулярное выражение.

Заранее спасибо за вашу помощь .

Ответы [ 3 ]

0 голосов
/ 01 апреля 2020

Вы можете использовать:

^(?:\d+\.\d+(?:[ ]+|$)){4}$

Демо

0 голосов
/ 02 апреля 2020

Вы можете использовать следующее регулярное выражение:

^(?:\s*(?:[1-9]|0(?=\.))\d*(?:\.\d+)?){4}\s*$

Демо

Если регулярное выражение совпадает со строкой, подстроки, представляющие числа, можно извлечь, разбив строку в одном или нескольких пробелах.

Если целые числа не разрешены (только с плавающей запятой), удалите знак вопроса из (?:\.\d+)?.

Следующие строки не сопоставлены по указанным причинам:

123.45    67.891  0.234
  # too few numbers
123.45    67.891  0.234   5678.90     12.34
  # too many numbers
123.45   .67.891  22      5678.90
  # .67.891 is incorrect
123.45   067.891  22      5678.90
  # 067.891 contains a leading zero 
123.45      .891  0.234   5678.90
  # .891 requires a leading zero to be correct

Если желательно, чтобы любой из двух последних примеров соответствовал, регулярное выражение могло бы быть отрегулировано в соответствии с

Механизм регулярного выражения выполняет следующие операции.

^              # match beginning of string
  (?:          # begin non-cap grp
    \s*        # match 0+ spaces 
    (?:        # begin non-cap grp
      [1-9]    # match a digit other than zero
      |        # or
      0        # match 0
      (?=\.)   # match '.' in positive lookahead
    )          # end non-cap grp
    \d*        # match 0+ digits
    (?:\.\d+)  # match '.' followed by 1+ digits in non-cap grp
    ?          # optionally match non-cap grp
  )            # end non-cap grp
  {4}          # execute non-cap grp 4 times
  \s*          # match 0+ spaces
  $            # match end of line
0 голосов
/ 01 апреля 2020
re.match(r'^(\s*\d+\.\d*){4}$',s5)

$ в конце регулярного выражения приводит к совпадению с концом строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...