На каком номере линии было найдено соответствие регулярных выражений?

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

Например, если я ищу соответствие hello с регулярными выражениями Java, будет ли какой-то метод сказать, что совпадения были найдены в строках 9, 15 и 30?

Ответ 1

Возможно... с Trickery Regex!

Отказ от ответственности: это не предназначено для практического решения, а является иллюстрацией способа использования расширения потрясающего руткима регулярных выражений. Более того, он работает только с механизмами регулярных выражений, которые позволяют группам захвата ссылаться на себя. Например, вы можете использовать его в Notepad ++, поскольку он использует механизм PCRE, но не в Java.

Скажем, ваш файл:

some code
more code
hey, hello!
more code

В нижней части файла вставьте :1:2:3:4:5:6:7, где : - разделитель, не найденный в остальной части кода, и где числа идут как минимум так же высоко, как количество строк.

Затем, чтобы получить строку первого hello, вы можете использовать:

(?m)(?:(?:^(?:(?!hello).)*(?:\r?\n))(?=[^:]+((?(1)\1):\d+)))*.*hello(?=[^:]+((?(1)\1)+:(\d+)))

Номер строки первой строки, содержащей hello, будет снят группой 2.

  • В демо, см. захват группы 2 в правой панели.
  • Хак полагается на группу, ссылающуюся на себя. В классическом трюке @Qtax это делается с помощью (?>\1?). Для разнообразия я использовал условное выражение.

Объяснение

  • Первая часть регулярного выражения - это шкипер строки, который фиксирует увеличивающееся количество счетчика строк внизу группы 1
  • Вторая часть регулярного выражения соответствует hello и фиксирует номер строки для группы 2
  • Внутри шкипера линии (?:^(?:(?!hello).)*(?:\r?\n)) соответствует строке, которая не содержит приветствия.
  • Внутри шкипера линии (?=[^:]+((?(1)\1):\d+)) lookahead возвращает нас к первому : с [^:]+, а внешние скобки в ((?(1)\1):\d+)) захватывают в группу 1... если группа 1 установлена ​​(?(1)\1), тогда Группа 1, то, независимо, двоеточие и некоторые цифры. Это гарантирует, что каждый раз, когда шкипер линии соответствует строке, группа 1 расширяется до большей части :1:2:3:4:5:6:7
  • * связывает шкипер линии с нулем или более раз
  • .*hello соответствует строке с hello
  • Смотрище (?=[^:]+((?(1)\1)+:(\d+))) идентично таковому в строке шкипера, за исключением того, что на этот раз цифры записываются в группу 2: (\d+)  -

Ссылка

Ответ 2

Если вы используете ОС/терминал на базе Unix, вы можете использовать sed:

sed -n '/regex/=' file

(из этого fooobar.com/questions/7969/...)

Ответ 3

В Java нет методов, которые сделают это для вас. Вы должны прочитать файл по очереди и проверить соответствие для каждой строки. Вы можете сохранить индекс строк по мере их чтения и делать все, что хотите, с этим индексом, когда совпадение найдено.