Регулярное совпадение, когда строка присутствует дважды

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

Я использую grepWin для поиска файлов. Мне нужно выполнить поиск, который вернет файлы с указанной строкой дважды.

Итак, например, если я искал слово "как", то файл один не соответствовал бы:

Здравствуйте
как вы сегодня?

но файл два будет:

Здравствуйте
как вы сегодня?

Я в порядке, как дела?

Кто-нибудь знает, как сделать RegEx, который будет соответствовать этому?

Ответ 1

что-то вроде этого (зависит от языка и вашей конкретной задачи)

\(how.*){2}\

Edit: в соответствии с @CodeJockey

\^(([^h]|h[^o]|ho[^w])*how([^h]|h[^o]|ho[^w])*){2,2}$\

(усложняется) @CodeJockey: Спасибо за комментарии

Ответ 2

Я не знаю, что поддерживает grepWin, но вот что я придумал, чтобы что-то совпадало ровно дважды.

/^((?!how).)*how((?!how).)*how((?!how).)*$/

Пояснение:

/^             # start of subject
  ((?!how).)*  # any text that does not contain "how"
  how          # the word "how"
  ((?!how).)*  # any text that does not contain "how"
  how          # the word "how"
  ((?!how).)*  # any text that does not contain "how"
$/             # end of subject

Это гарантирует, что вы найдете два "способа", но тексты между "как" и с каждой из них не содержат "как" .

Конечно, вы можете заменить любую строку "как" в выражении.


Если вы хотите "упростить", только дважды записывая выражение поиска, вы можете использовать обратные ссылки таким образом:

/^(?:(?!how).)*(how)(?:(?!\1).)*\1(?:(?!\1).)*$/

Refiddle с этим выражением

Объяснение:
Я добавил ?:, чтобы текст негативного внешнего вида не был захвачен. Затем я добавил круглые скобки вокруг регулярного how, чтобы сделать подпанель захвата (первая и единственная).

Мне пришлось включить "как" снова в первый взгляд, потому что это отрицательный взгляд (это означает, что любой захват не будет содержать "как" ), а захваченное "как" еще не захвачено в этой точке.

Ответ 3

Это значительно сложнее, чем я думал изначально, и требует переменную длину lookbehind, которую grepWin не поддерживает...

это выражение:

 (?<!blah.{0,99999})blah(?=.*?blah)(?!.*blah.*blah)

был успешно использован в Eclipse, используя диалог "Поиск > Файл", чтобы исключить файлы с одним и тремя экземплярами blah и включить файлы с ровно двумя экземплярами blah.

Eclipse не разрешает .* в lookbehind, поэтому я использовал .{0,99999}.

Возможно, с правильным инструментом, но не очень приятно заставить его работать с grepWin (см. ответ выше). Можете ли вы использовать другие инструменты (например, Eclipse) и что вы хотите делать с файлами после этого?