Как получить обратное регулярное выражение? - PullRequest
2 голосов
/ 17 июля 2009

Допустим, у меня есть регулярное выражение, которое работает правильно, чтобы найти все URL-адреса в текстовом файле:

(http://)([a-zA-Z0-9\/\.])*

Если то, что я хочу, это не URL-адреса, а обратный - весь остальной текст, кроме URL-адресов - есть ли простое изменение, чтобы получить это?

Ответы [ 4 ]

7 голосов
/ 17 июля 2009

Вы можете просто найти и заменить все, что соответствует регулярному выражению, пустой строкой, например, в Perl s/(http:\/\/)([a-zA-Z0-9\/\.])*//g

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

4 голосов
/ 17 июля 2009

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

((?<=http://[a-zA-Z0-9\/\.#?/%]+(?=[^a-zA-Z0-9\/\.#?/%]))|\A(?!http://[a-zA-Z0-9\/\.#?/%])).+?((?=http://[a-zA-Z0-9\/\.#?/%])|\Z)

Я немного расширил набор символов URL ([a-zA-Z0-9\/\.#?/%]), добавив несколько важных, но это ни в коем случае не является точным или исчерпывающим.

Регулярное выражение - нечто вроде монстра, поэтому я постараюсь разобрать его:

(?<=http://[a-zA-Z0-9\/\.#?/%]+(?=[^a-zA-Z0-9\/\.#?/%])

Первое зелье соответствует концу URL. http://[a-zA-Z0-9\/\.#?/%]+ соответствует самому URL, в то время как (?=[^a-zA-Z0-9\/\.#?/%]) утверждает, что за URL должен следовать не-URL-символ, чтобы мы были уверены, что мы в конце. Взгляд в будущее используется так, что не-URL-символ ищется, но не захватывается. Все это заворачивается в вид сзади (?<=...), чтобы найти его как границу матча, опять же без захвата этой части.

Мы также хотим сопоставить не-URL в начале файла. \A(?!http://[a-zA-Z0-9\/\.#?/%]) соответствует началу файла (\A), за которым следует отрицательный просмотр, чтобы убедиться, что в начале файла не скрывается URL. (Эта проверка URL проще, чем первая, потому что нам нужно только начало URL, а не все.)

Обе эти проверки заключены в круглые скобки и OR 'd вместе с символом |. После этого .+? соответствует строке, которую мы пытаемся захватить.

Тогда мы подходим к ((?=http://[a-zA-Z0-9\/\.#?/%])|\Z). Здесь мы проверяем начало URL, еще раз с (?=http://[a-zA-Z0-9\/\.#?/%]). Конец файла также является довольно хорошим признаком того, что мы достигли конца нашего матча, поэтому мы должны искать это, используя \Z. Подобно первой большой группе, мы заключаем ее в круглые скобки и OR две возможности вместе.

Символу | требуется скобка, так как его приоритет очень мал, поэтому вы должны явно указать границы OR.

Это регулярное выражение в значительной степени опирается на утверждения нулевой ширины (якоря \A и \Z и группы обхода). Вы всегда должны понимать регулярное выражение, прежде чем использовать его для чего-либо серьезного или постоянного (в противном случае вы можете обнаружить случай с Perl), поэтому вы можете проверить Начало строки и Конец строки Якоря и Lookahead и Lookbehind Утверждения нулевой ширины .

Исправления приветствуются, конечно!

1 голос
/ 17 июля 2009

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

s/^(.*)(your regex here)(.*)$/$1$3/
0 голосов
/ 17 июля 2009

Я не уверен, будет ли это работать именно так, как вы намереваетесь, но это может помочь: Все, что вы поместите в скобки [], будет сопоставлено. Если вы поставите ^ в скобки, то есть [^ a-zA-Z0-9 /.], Он будет соответствовать всему , кроме того, что в скобках.

http://www.regular -expressions.info /

...