Нахождение последнего вхождения слова
У меня есть следующая строка:
<SEM>electric</SEM> cu <SEM>hello</SEM> rent <SEM>is<I>love</I>, <PARTITION />mind
Я хочу найти последний стартовый тег "SEM" перед тегом "PARTITION". не конечный тег SEM, а начальный тег. Результат должен быть:
<SEM>is <Im>love</Im>, <PARTITION />
Я пробовал это регулярное выражение:
<SEM>[^<]*<PARTITION[ ]/>
но это работает только в том случае, если заключительные теги "SEM" и "PARTITION" не имеют никаких других тегов между ними. Есть идеи?
6 ответов
А вот и ваш тупой Регекс!!!
(?=[\s\S]*?\<PARTITION)(?![\s\S]+?\<SEM\>)\<SEM\>
Это означает, что "где-то впереди есть тег PARTITION... но пока впереди нет другого тега SEM... соответствует тегу SEM".
Наслаждайтесь!
Вот это регулярное выражение:
(?=[\s\S]*?\<PARTITION) means "While ahead somewhere is a PARTITION tag"
(?![\s\S]+?\<SEM\>) means "While ahead somewhere is not a SEM tag"
\<SEM\> means "Match a SEM tag"
Используйте String.IndexOf для поиска PARTITION и String.LastIndexOf для поиска SEM?
int partitionIndex = text.IndexOf("<PARTITION");
int emIndex = text.LastIndexOf("<SEM>", partitionIndex);
Если вы собираетесь использовать регулярное выражение, чтобы найти последнее вхождение чего-либо, вы можете также использовать опцию регулярного выражения синтаксического анализа справа налево:
new Regex("...", RegexOptions.RightToLeft);
Решение заключается в следующем, я проверил в http://regexlib.com/RETester.aspx
<\s*SEM\s*>(?!.*</SEM>.*).*<\s*PARTITION\s*/>
Как вы хотите последний, единственный способ определить, это найти только символы, которые не содержат </SEM>
,
Я включил "\s*" на случай, если в <SEM> or <PARTITION/>
,
По сути, мы исключаем слово </SEM>
с:
(?!.*</SEM>.*)
Немного быстро и грязно, но попробуйте это:
(<SEM>.*?</SEM>.*?)*(<SEM>.*?<PARTITION)
и посмотрите, что находится в C#/. Чистый эквивалент $2
Секрет кроется в лениво-соответствующей конструкции (.*?) --- Я предполагаю / надеюсь, что C# поддерживает это.
Понятно, что решение Jon Skeet будет работать лучше, но вы можете использовать регулярные выражения (например, для упрощения разбиения интересующих вас битов).
(Отказ от ответственности: я сам Perl/Python/Ruby человек...)
Вы пробовали это:
<EM>.*<PARTITION\s*/>
Ваше регулярное выражение совпадало с чем угодно, кроме "<" после тега "EM". Следовательно, он прекращает сопоставление, когда попадает на закрывающий тег "EM".