регулярное выражение для сопоставления с шаблоном <Key>.... <Value> - PullRequest
1 голос
/ 06 июля 2010

У меня есть следующие данные, отправленные внешней системой, которые необходимо проанализировать для определенного ключа

<ContextDetails>
<Context><Key>ID</Key><Value>100</Value></Context>
<Context><Key>Name</Key><Value>MyName</Value></Context>
</ContextDetails>

Я попытался проанализировать это с помощью регулярного выражения, чтобы получить значение для ключа: Имя

<Context><Key>Name</Key><Value>.</Value></Context>

, но результат не указан

Что мне нужно сделать, чтобы исправить это регулярное выражение

Ответы [ 5 ]

5 голосов
/ 06 июля 2010

Если это XML, загрузите его в XDocument и запросите его.

См. ответ от @Jens для получения подробной информации о том, как это сделать..

3 голосов
/ 06 июля 2010

Если развернуть Ответ Одеда , то, как вы должны это сделать, примерно так:

XDocument doc = XDocument.Parse(@"<ContextDetails> 
<Context><Key>ID</Key><Value>100</Value></Context> 
<Context><Key>Name</Key><Value>MyName</Value></Context> 
</ContextDetails>");

String name  =  doc.Root.Elements("Context")
                        .Where(xe => xe.Element("Key").Value == "Name")
                        .Single()
                        .Element("Value").Value;
1 голос
/ 06 июля 2010

По-моему, вы делаете это неправильно. Вы должны использовать XML Parser. http://www.tutorialspoint.com/ruby/ruby_xml_xslt.htm Это просто руководство. Это может помочь.

1 голос
/ 06 июля 2010

Я думаю, выражение Reg-Ex для соответствия всем парам ключ-значение, которые вам нужны:

<Context>\s*?<Key>(.*?)\</Key>\s*?<Value>(.*?)</Value>\s*?</Context>

Описание:

// <Context>\s*?<Key>(.*?)\</Key>\s*?<Value>(.*?)</Value>\s*?</Context>
// 
// Match the characters "<Context>" literally «<Context>»
// Match a single character that is a "whitespace character" (spaces, tabs, line breaks, etc.) «\s*?»
//    Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
// Match the characters "<Key>" literally «<Key>»
// Match the regular expression below and capture its match into backreference number 1 «(.*?)»
//    Match any single character that is not a line break character «.*?»
//       Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
// Match the character "<" literally «\<»
// Match the characters "/Key>" literally «/Key>»
// Match a single character that is a "whitespace character" (spaces, tabs, line breaks, etc.) «\s*?»
//    Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
// Match the characters "<Value>" literally «<Value>»
// Match the regular expression below and capture its match into backreference number 2 «(.*?)»
//    Match any single character that is not a line break character «.*?»
//       Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
// Match the characters "</Value>" literally «</Value>»
// Match a single character that is a "whitespace character" (spaces, tabs, line breaks, etc.) «\s*?»
//    Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
// Match the characters "</Context>" literally «</Context>»

Использование:

using System.Text.RegularExpressions;
public static void RunSnippet()
    {
        Regex RegexObj = new Regex("<Context>\\s*?<Key>(.*?)\\</Key>\\s*?<Value>(.*?)</Value>\\s*?</Context>",
            RegexOptions.IgnoreCase | RegexOptions.Multiline);
        Match MatchResults = RegexObj.Match(@"<ContextDetails>
            <Context><Key>ID</Key><Value>100</Value></Context>
            <Context><Key>Name</Key>   <Value>MyName</Value></Context>
            </ContextDetails>
            ");
        while (MatchResults.Success){
            Console.WriteLine("Key: " + MatchResults.Groups[1].Value)   ;
            Console.WriteLine("Value: " + MatchResults.Groups[2].Value) ;
            Console.WriteLine("----");
            MatchResults = MatchResults.NextMatch();
        }
    }
    /*
    Output:

        Key: ID
        Value: 100
        ----
        Key: Name
        Value: MyName
        ----
    */

Регулярное выражение для математического вычисления только значения или ключа "Имя":

<Context>\s*?<Key>Name</Key>\s*?<Value>(.*?)</Value>\s*?</Context>

Описание:

// <Context>\s*?<Key>Name</Key>\s*?<Value>(.*?)</Value>\s*?</Context>
// 
// Match the characters "<Context>" literally «<Context>»
// Match a single character that is a "whitespace character" (spaces, tabs, line breaks, etc.) «\s*?»
//    Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
// Match the characters "<Key>Name</Key>" literally «<Key>Name</Key>»
// Match a single character that is a "whitespace character" (spaces, tabs, line breaks, etc.) «\s*?»
//    Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
// Match the characters "<Value>" literally «<Value>»
// Match the regular expression below and capture its match into backreference number 1 «(.*?)»
//    Match any single character that is not a line break character «.*?»
//       Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
// Match the characters "</Value>" literally «</Value>»
// Match a single character that is a "whitespace character" (spaces, tabs, line breaks, etc.) «\s*?»
//    Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
// Match the characters "</Context>" literally «</Context>»

Использование:

string SubjectString = @"<ContextDetails>
            <Context><Key>ID</Key><Value>100</Value></Context>
            <Context><Key>Name</Key>   <Value>MyName</Value></Context>
            </ContextDetails>
            ";
    Console.WriteLine( Regex.Match(SubjectString, "<Context>\\s*?<Key>Name</Key>\\s*?<Value>(.*?)</Value>\\s*?</Context>",
            RegexOptions.IgnoreCase | RegexOptions.Multiline).Groups[1].Value );
0 голосов
/ 06 июля 2010

Можете ли вы использовать синтаксический анализатор XML? Если так, то используйте его, это правильный инструмент для этой работы.

Если у вас есть, скажем, текстовый редактор и вы хотите проверять каждое совпадение вручную, то вы можете использовать регулярное выражение. Ошибка в вашем регулярном выражении заключается в том, что . соответствует только одному символу (любой символ, кроме новой строки). Поэтому вам нужно заменить это на .*? (соответствует любому количеству символов, но как можно меньше) или, что лучше, [^<]*.

Последний означает «ноль или более символов, кроме <» (который является символом-разделителем). Конечно, это может работать только в том случае, если внутри значения, которое вы ищете, никогда не будет <.

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

Обновление: я только что видел ваше редактирование: у вас есть доступ к анализатору XML - переходите к ответу Одеда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...