Найти повторение с помощью регулярного выражения Вима - PullRequest
2 голосов
/ 07 октября 2009

Как найти повторяющиеся последовательности не менее чем из 30 чисел?

Образец данных

2.3758542141230068337129840546697038724373576309794988610478359908883826879271070615034168564920273348519362186788154897494305239179954441913439635535307517084282460136674259681093394077448747152619589977220956719817767653758542141230068337129840546697038724373576309794988610478359908883826879271070615034168564920273348519362186788154897494305239179954441913439635535307517084282460136674259681093394077448747152619589977220956719817767653758542141230068337129840546697038724373576309794988610478359908883826879271070615034168564920273348519362186788154897494305239179954441913439635535307517084282460136674259681093394077448747152619589977220956719817767653758542141230068337129840546697038724373576309794988610478359908883826879271070615034168564920273348519362186788154897494305239179954441913439635535307517084282460136674259681093394077448747152619589977220956719817767653758542141230068337129840546697038724373576309794988610478359908883826879271070615034168564920273348519362186788154897494305239179954441913439635535307517084282460136674259681093394077448747152619589977220956719817767653758542141230068337129840546697038724373576309794988610478359908883826879271070615034168564920273348519362186788154897494305239179954441913439635535307517084282460136674259681093394077448747152619589977220956719817767653758542141230068337129840546697038724373576309794988610478359908883826879271070615034168564920273348519362186788154897494305239179954441913439635535307517084282460136674259681093394077448747152619589977220956719817767653758542141230068337129840546697038724373576309794988610478359908883826879271070615034168564920273348519362186788154897494305239179954441913439635535307517084282460136674259681093394077448747152619589977220956719817767653758542141230068337129840546697038724373576309794988610478359908883826879271070615034168564920273348519362186788154897494305239179954441913439635535307517084282460136674259681093394077448747152619589977220956719817767653758542141230068337129840547

Моя попытка в Vim

:g/\(\d\{4}\)\[^\1\]\1/
                |
                |----------- Problem here!

Я не знаю, как вы можете получить отрицание первого шара.

Ответы [ 5 ]

2 голосов
/ 08 октября 2009

Прежде всего, чтобы найти повторяющиеся числа, вы можете воспользоваться этим простым поиском:

/\(\d\{5\}\).\{-}\1

Этот поиск находит повторения из 5 цифр. К сожалению, vim выделяет от начала 5-значного числа до конца повторения - , включая каждую цифру между - и это затрудняет понимание того, что такое 5-значное число. Кроме того, поскольку ваша числовая последовательность повторяется так много, все это выделяется, потому что они повторяются на всем протяжении.

Вы, вероятно, сочтете более полезным использовать :set incsearch и набирать /\(\d\{5\}\).\{-}\1 или /\(\d\{5\}\)\ze.\{-}\1 , не нажимая Enter , чтобы вы могли видеть, какие цифры есть.

Эта команда может быть более полезной для вас:

:syn region repeatSection matchgroup=Search start=/\z(\d\{30}\)/ matchgroup=Error end=/\z1/ oneline

Это выделит последовательность из 30 цифр желтым (при первом просмотре) или красным (при повторении). Обратите внимание , что это работает только для одной строки текста (многострочный невозможен).

2 голосов
/ 07 октября 2009

Я не уверен, зачем тебе нужно отрицание. /\(\d\{4\}\)\1/ будет соответствовать последовательности (точно) четырех цифр, повторенных один раз. Вы, вероятно, на самом деле хотите что-то вроде /\(\d\{30,\}\)\1/, чтобы получить свои "по крайней мере 30". Похоже, это работает для меня, если я не понял, что вы пытаетесь найти. Обратите внимание, что, поскольку регулярные выражения являются жадными, вы получите максимально возможную повторяющуюся последовательность.

2 голосов
/ 07 октября 2009

Как насчет :g/\(\d\{30,\}\{2,\}\)/?

0 голосов
/ 08 октября 2009

Эта команда будет сопоставлять строки с 123451234, но не 111111111

:g/\(\d\{4}\)\1\@!.\1/
  • \1\@!. использует отрицательный взгляд, чтобы сказать «убедитесь, что эта позиция не соответствует (\@!) группе 1 (\1), затем используйте символ (.
0 голосов
/ 07 октября 2009

Если это поможет вам в пути, соответствующий способ убедиться, что следующий набор символов не совпадает с тем, что хранится в обратной ссылке # 1, будет (?!\1). Обратите внимание, что группа (?!) (отрицательный прогноз) является утверждением нулевой ширины (то есть она не изменит положение курсора, она просто проверяет, должно ли регулярное выражение быть неудачным.)

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

Обновление

У меня только что был быстрый набросок на бумаге, и что-то вроде этого могло бы работать в PCRE ... но я не проверял и не могу сейчас, но, возможно, это даст вам некоторые идеи:

(?=(\d{30}))\d(?=\d{29,}?\1)

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

Мои мысли о приведенном выше регулярном выражении были такими:

  1. Сначала я хочу сопоставить последовательность из 30 цифр, но я не хочу использовать их, так как я хочу проверить 1 цифру позже (не 30) в следующий раз. Поэтому я использую прогнозную группу с группой захвата, которая хранит следующие 30 цифр.
  2. Затем я использую одну цифру, чтобы убедиться, что я не сопоставляю 30 цифр с самими собой.
  3. Затем я сопоставляю как минимум 29 цифр (что означает, что я начну с цифры, находящейся за пределами текущей последовательности цифр) с не жадным квантификатором, так что он будет пытаться использовать 30, затем 31 и т. Д.
  4. Тогда я сопоставляю 30 цифр, которые я сейчас тестирую. Если они существуют позже в последовательности, регулярное выражение выполнится успешно; в противном случае произойдет сбой.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...