2009-07-22 1 views
1

Как вы можете найти значение повторяющейся строки и данные между ней с помощью регулярных выражений? Например, возьмите этот фрагмент XML:Как найти повторяющуюся строку и значение между ними с помощью регулярных выражений?

<tagName>Data between the tag</tagName> 

Что было бы правильным регулярным выражением, чтобы найти эти значения? (Обратите внимание, что tagName может быть любым).

Я нашел способ, который работает, что включает в себя поиск всех tagName S, которые между ними набором < >, а затем поиском первого экземпляром tagName от открывающего тега до конца строки, а затем найти закрытие </tagName> и выработать данные между ними. Тем не менее, это чрезвычайно неэффективно и сложно. Должен быть более простой способ!

EDIT: Пожалуйста, не говорите мне использовать XMLReader; Я сомневаюсь, что когда-либо буду использовать свой собственный класс для чтения XML, я пытаюсь изучить лучший способ сделать это (и неправильные способы), пытаясь сделать свой собственный.

Заранее спасибо.

+0

Ну - это звучит немного элегантным, но я не имею в виду его Таким образом, вы определенно находитесь на правильном пути для изучения одного из неправильных способов. Роль регулярных выражений в построении XML-читателя играет роль, но в сканировании, а не в синтаксическом анализе. –

+0

А, наверное, ты прав. Мне это удалось, когда у вас есть только и так далее, но он падает до битов, когда добавляется или что-то еще, и я не вижу, как его адаптировать для работы. –

ответ

5

Вы можете использовать: <(\w+)>(.*?)<\/\1>

Group # 1 является тегом, группа № 2 является содержание ,

+0

Спасибо, это действительно полезно. –

0

с Perl:

my $tagName = 'some tag'; 
my $i; # some line of XML 
$i =~ /\<$tagName\>(.+)\<\/$tagname\>/; 

где $ 1 теперь заполнен данными вы захватили

+0

Я знал это уже из perl, и вопрос о C#. –

+0

извините C Rogers - Мне не удалось прочитать все теги! – dls

2

Вы можете использовать как \1 обратной ссылки, чтобы обратиться к более раннему матча:

@"<([^>]*)>(.*)</\1>" 

\1 будет соответствовать тому, что был захвачен в первой группе в круглых скобках.

3

Использование регулярных выражений для синтаксического анализа XML - ужасная ошибка.

Это эффективно (не разобрать XML в DOM) и достаточно просто:

string s = "<tagName>Data between the tag</tagName>"; 

using (XmlReader xr = XmlReader.Create(new StringReader(s))) 
{ 
    xr.Read(); 
    Console.WriteLine(xr.ReadElementContentAsString()); 
} 

Edit:

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

Рассмотрим довольно тривиальный случай испытания:

<a><b><a>text1<b>CDATA<![<a>text2</a>]]></b></a></b>text3</a> 

В этом XML есть два элемента с именем тега «a». Первый имеет один дочерний элемент текстового узла со значением «text1», а второй имеет один дочерний элемент текстового узла со значением «text3». Кроме того, есть элемент «b», который содержит строку текста, которая выглядит как элемент «a», но не потому, что она заключена в раздел CDATA.

Вы не можете разобрать это с помощью простого сопоставления с образцом. Поиск <a> и ищем, чтобы найти </a> не начало, чтобы сделать то, что вам нужно.Вы должны поместить стартовые теги в стек, как вы их находите, и вытащить их из стека по мере приближения к соответствующему концевому тегу. У вас должно быть stop положить что-нибудь в стек, когда вы столкнетесь с началом раздела CDATA, а не начинать снова, пока не столкнетесь с концом.

И это без ввода пробелов, пустых элементов, атрибутов, инструкций по обработке, комментариев или Unicode в проблему.

+0

Я пытаюсь создать свой собственный «XMLReader». Это не будет быстрым/эффективным/полезным или когда-либо используемым, но я думаю, что люди должны пытаться строить вещи с нуля, а не прибегать к API-интерфейсам все время, поэтому они, по крайней мере, знают идеи, стоящие за ним, и почему код они созданный был настолько плохим. Вы действительно компьютерный ученый, если вы не можете быстро умножить или даже изменить строку без использования .NET/Java/whatever, встроенного в библиотеку. Возможно нет. Однако вы можете быть правы относительно регулярных выражений. Тем не менее, я постараюсь, затем потерпит неудачу, а потом узнаю. –

+0

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

+0

Конечно, я просто чувствовал, что должен объяснять свои действия, выбирая сложный/неудачный корень. –

0

Забегая вперед, если вы застряли проверить regexlib.com

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

Смежные вопросы