Регулярное выражение для получения значения в теге - PullRequest
0 голосов
/ 15 ноября 2009

Мне вернули образец набора XML:

<rsp stat="ok">
  <site>
    <id>1234</id>
    <name>testAddress</name>
    <hostname>anotherName</hostname>
    ...

  </site>
  <site>
    <id>56789</id>
    <name>ba</name>
    <hostname>alphatest</hostname>
    ...
  </site>
</rsp>

Я хочу извлечь все внутри <name></name>, но не сами теги, и иметь это только для первого экземпляра (или на основе какого-либо другого теста выберите какой элемент).

Возможно ли это с помощью регулярных выражений?

Ответы [ 5 ]

3 голосов
/ 15 ноября 2009

<disclaimer> Я не использую Objective-C </disclaimer>

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

Никогда не используйте регулярные выражения или синтаксический анализ строк для обработки XML . Каждый распространенный язык сейчас имеет отличную поддержку XML. XML - обманчиво сложный стандарт, и вряд ли ваш код будет правильным в том смысле, что он будет правильно анализировать все правильно сформированные входные данные XML, и даже если это так, вы тратите свое время, потому что (как только что упоминалось) каждый язык общее использование имеет поддержку XML. Использовать регулярные выражения для анализа XML непрофессионально.

Вы можете использовать Expat , с привязками Objective C .

Опции Apple :

  1. Анализатор CF xml
  2. Анализатор какао на основе дерева (только 10.4)
2 голосов
/ 15 ноября 2009

Не зная вашего языка или среды, вот некоторые выражения perl. Надеюсь, это даст вам правильную идею для вашего приложения.

Ваше регулярное выражение для захвата текстового содержимого тега будет выглядеть примерно так:

m/>([^<]*)</

Это будет захватывать содержимое в каждом теге. Вам придется зацикливаться на совпадении, чтобы извлечь весь контент. Обратите внимание, что это не учитывает самозавершающиеся теги. Для этого вам понадобится движок регулярных выражений с негативными взглядами. Не зная вашей среды, трудно сказать, будет ли она поддерживаться.

Вы также можете просто удалить все теги из вашего источника, используя что-то вроде:

s/<[^>]*>//g

Также, в зависимости от вашей среды, если вы сможете использовать библиотеку XML-синтаксического анализа, это значительно облегчит вашу жизнь. В конце концов, используя подход регулярных выражений, вы теряете все, что вам действительно предлагает XML (структурированные данные, контекстная осведомленность и т. Д.).

1 голос
/ 23 декабря 2009

Лучший инструмент для такого рода задач - XPath .

NSURL *rspURL = [NSURL fileURLWithPath:[@"~/rsp.xml" stringByExpandingTildeInPath]];
NSXMLDocument *document = [[[NSXMLDocument alloc] initWithContentsOfURL:rspURL options:NSXMLNodeOptionsNone error:NULL] autorelease];

NSArray *nodes = [document nodesForXPath:@"/rsp/site[1]/name" error:NULL];
NSString *name = [nodes count] > 0 ? [[nodes objectAtIndex:0] stringValue] : nil;

Если вам нужно имя сайта с идентификатором 56789, используйте вместо этого XPath: /rsp/site[id='56789']/name. Я предлагаю вам прочитать учебник по W3Schools XPath для краткого обзора синтаксиса XPath.

1 голос
/ 15 ноября 2009

Как говорят другие, вы действительно должны использовать NSXMLParser для такого рода вещей.

ОДНАКО, если вам только нужно извлечь материал из тегов имен, то RegexKitLite может сделать это довольно легко:

NSString * xmlString = ...;
NSArray * captures = [xmlString arrayOfCaptureComponentsMatchedByRegex:@"<name>(.*?)</name>"];
for (NSArray * captureGroup in captures) {
  NSLog(@"Name: %@", [captureGroup objectAtIndex:1];
}
0 голосов
/ 15 ноября 2009

Осторожнее с пространствами имен:

<prefix:name xmlns:prefix="">testAddress</prefix:name>

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

./rsp/site/name/text()

Какао имеет NSXML поддержку XPath .

...