Помогите с отрицательным взглядом в регулярных выражениях - PullRequest
0 голосов
/ 16 июля 2009

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

Поскольку ASP.NET разбивает на части записи ответа, мой фильтр вызывается несколько раз, прежде чем страница полностью передается в потоковом режиме. Это означает, что мне нужно быть осторожным, чтобы каждый вызов Regex.Replace не заменял дважды URL-адрес (в итоге вы получите http://foo.comhttp://foo.com/path).

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

    content = Regex.Replace(content,"((?<!" + newDomain + ")" + match + ")", newDomain + match); 

Это создает регулярное выражение, подобное:

 ((?<!http://www.foo.com/)actual/url)

Тем не менее, кажется, что я не уважаю взгляд позади, и я заменяю все дважды.

Есть идеи?

РЕДАКТИРОВАТЬ: Это регулярное выражение прекрасно работает, когда я использую такой инструмент, как Regex Coach, чтобы проверить его на примере данных.

РЕДАКТИРОВАТЬ 2: Добавил косую черту, он на самом деле там.

Ответы [ 5 ]

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

Я попробую третий угол.

Я думаю, что вы путаете тот факт, что ваше регулярное выражение "соответствует" чему-то в тренере регулярных выражений, а оно соответствует той части, которую вы хотите. Поэтому вы удивлены результатами замены.

замена замен все соответствующие входные данные для нового токена.

отрицательный взгляд за спиной гарантирует, что шаблон отсутствует, но шаблон не является частью согласованного ввода .

результат, который вы получаете, заключается в том, что только путь (строка соответствия) вашего URL является согласованным вводом , и вы заменяете его переменной newDomain.

Вот почему вы получаете результаты, которые вы получаете.

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

Пара мыслей:

  • Вам нужно сбежать. в регулярных выражениях? Я не знаю синтаксис <! и у меня нет книг, поэтому это может быть спорным вопросом.
  • Я не вижу, как это будет соответствовать http://www.foo.com/something, поскольку в вашем примере нет / после www.foo.com.

Надеюсь, что это поможет.

0 голосов
/ 07 октября 2011

Как насчет идеи его замены только в том случае, если вы не нашли в строке заменяемую часть домена?

То есть, неправильно использовать perl как стенографию:

if ($string !~ /foo\.com) {
  $string = $domain . $string;
}
0 голосов
/ 16 июля 2009

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

Так что должно быть что-то вроде этого:

Regex.Replace("http://www.foo.com/something", "(http://www.foo.com/)(something)", "http://www.abc.com/$2")

Идея состоит в том, чтобы использовать группирование в ваших интересах. Вот где часть за 2 доллара захватит вторую половину совпадения (путь) и добавит его в новый домен. Я протестировал это в Regex Hero (тестер регулярных выражений .NET), и это работает. Кстати, Regex Coach основан на Perl, и вы можете столкнуться с некоторыми отличиями при сравнении с .NET regex engine.

0 голосов
/ 16 июля 2009

Я бы попробовал это

content = Regex.Replace(content,"(?<!" + newDomain + ")^[^/]+/(?=" + match + ")", newDomain + match);

Это будет соответствовать (и, следовательно, заменять часть домена в выражении) только в том случае, если домен не newDomain и путь соответствует.

...