Как найти, что HTML-div содержит определенный текст после текстового префикса? - PullRequest
0 голосов
/ 06 августа 2010

У меня есть следующая строка:

<div> text0 </div> prefix <div> text1 <strong>text2</strong> text3 </div> text4

и хотите знать, содержит ли он text3 внутри div, которые идут после префикса:

prefix<div>...text3...</div>

но я не знаю, как сделать для этого регулярное выражение, поскольку я не могу использовать [^<]+, потому что div может содержать тег strong внутри.

Пожалуйста, помогите

EDIT:

  1. Теги Div после префикса гарантированно не являются вложенными
  2. Язык C #
  3. Text4 очень длинный, поэтому регулярное выражение не должно выглядеть после закрытия div

EDIT2: я не хочу использовать html-парсер, его легко (и НАМНОГО быстрее) достичь с помощью Regex. HTML там прост: нет атрибутов в тегах; нет вложенных div'ов. И даже несколько% неправильных ответов приемлемы в моем случае.

Ответы [ 3 ]

2 голосов
/ 06 августа 2010

Если вы отключите «жадную» опцию, вы сможете использовать что-то вроде prefix<div>.*text3.*</div>. (Если <div> разрешено иметь атрибуты, используйте prefix<div[^>]*>.*text3.*</div>.)

Многочисленные улучшения могут быть сделаны для учета необычного интервала, > с в кавычках, </div> в кавычках и т. Д.

Шаблоны типа prefix<div>...<div></div>text3</div> были бы более сложными. Возможно, вам придется захватить все вхождения тега div, чтобы можно было подсчитать, сколько тегов div было открыто в данный момент времени.

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

0 голосов
/ 06 августа 2010

это мое новое регулярное выражение:

prefix<div>([^<]*<(?!/div>))*[^<]*text3([^<]*<(?!/div>))*[^<]*</div>

вроде бы нормально работает.

0 голосов
/ 06 августа 2010

Для C # + HtmlAgilityPack вы можете сделать что-то вроде:

InputString = Regex.Replace(InputString,"^(?:[^<]+?|<[^>]*>)*?prefix","");

HtmlDocument doc = new HtmlDocument();

doc.LoadHtml(InputString);

HtmlNode node = doc.DocumentNode.SelectSingleNode("//div[contains('text3')]");

Удаление префикса все еще не является хорошим способом борьбы с ним.В идеале вы должны сделать что-то вроде использования HtmlAgilityPack, чтобы найти, где в DOM находится prefix, перевести это, чтобы указать положение в строке, а затем выполнить подстроку (pos, len) (или эквивалентную), чтобы посмотреть только соответствующий текст(вы также можете не смотреть на text4 с помощью аналогичного метода).
Боюсь, я не могу перевести все это в код прямо сейчас;надеюсь, кто-то еще может помочь там.

(оригинальный ответ, перед предоставлением дополнительной информации)
Вот решение JavaScript + jQuery :

var InputString = '<div>text0 </div> prefix <div>text1 <strong>text2</strong> text3 </div> text4';

InputString = InputString.replace(/^.*?prefix/,'');

var MatchingDivs = jQuery('div:contains(text3)','<div>'+InputString+'</div>')

console.log(MatchingDivs.get());

Это использует способность jQuery принимать контекст в качестве второго аргумента (хотя, похоже, это нужно заключить в теги div, чтобы он действительно работал).

...