2016-12-19 6 views
4

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

Hello World <Red>This is some red text </Red> This is normal <Blue>This is blue text </Blue> 

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

<(?<tag>\w*)>(?<text>.*)</\k<tag>> 

Однако это возвращает

tag: Red 
text: This is some red text 
tag: Blue 
text this is blue text 

Что мне нужно чтобы получить совпадения для немаркированного контента, поэтому я бы получил 4 матча, два, как указано выше, а также «Hello World» и «Это нормально».

Возможно ли это с регулярным выражением?

Для примера это моя функция тока:

public static List<FormattedConsole> FormatColour(string input) 
    { 
     List<FormattedConsole> formatted = new List<FormattedConsole>(); 
     Regex regex = new Regex("<(?<Tag>\\w+)>(?<Text>.*?)</\\1>", RegexOptions.IgnoreCase 
       | RegexOptions.CultureInvariant 
       | RegexOptions.IgnorePatternWhitespace 
       | RegexOptions.Compiled 
     ); 

     MatchCollection ms = regex.Matches(input); 

     foreach (Match match in ms) 
     { 
      GroupCollection groups = match.Groups; 
      FormattedConsole format = new FormattedConsole(groups["Text"].Value, groups["Tag"].Value); 
      formatted.Add(format); 
     } 

     return formatted; 
    } 

Как уже упоминалось это возвращает только матчи между тегами. Мне также нужно получить текст без тегов.

(кстати FormattedConsole это просто контейнер, который содержит текст и цвет)

+0

Как это связано с WPF? – Clemens

+0

Является ли входной XML или он просто похож на XML? –

+0

@Clemens Извините, что я виноват, я привык отмечать как WPF, потому что многие мои вопросы требуют разных ответов, потому что я работаю в WPF. Сила привычки. – Ben

ответ

2

Вы можете попробовать это:

string sentence = "Hello World <Red>This is some red text </Red> This is normal <Blue>This is blue text </Blue>"; 
string[] matchSegments = Regex.Split(sentence,@"(<\w+>)(.*?)<\/\w+>"); 
foreach (string value in matchSegments) 
{ 
    if(value.Contains("<") && value.Contains(">")) 
     Console.Write(value); 
    else 
     Console.WriteLine(value); 
} 

Выход:

Hello World 
<Red>This is some red text 
This is normal 
<Blue>This is blue text 

Run the code here

+0

Спасибо за ответ. Думаю, я мог бы использовать это, а затем запустить второе регулярное выражение на строках, содержащих тег, чтобы вытащить из него цвет. Я попробую. Благодарю. – Ben

+0

удаление углов даст цвет, просто удалите <> внутри, если условие ..., что будет делать –

+0

Или, может быть, '@" <(\w+)> (. *?) "' даст чистые результаты. Или даже '@" <(\w+)> (. *?) «' –

2

Если вы хотите попробовать мастерить с XML вы можете попробовать решение, как этот. Мы будем использовать Linq. Попробуйте онлайн: https://dotnetfiddle.net/J4zVMY

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Xml.Linq; 

public class Program 
{ 
    public static void Main() 
    { 
     string response = @"Hello World <Red>This is some red text </Red> This is normal <Blue>This is blue text </Blue>"; 
     response = @"<?xml version='1.0' encoding='utf-8'?><root>"+response+"</root>"; 
     var doc = XDocument.Parse(response); 

     // fill all node in a list of Text 
     var colors = new List<Text>(); 
     foreach (var hashElement in doc.Descendants().Skip(1).Where(node => !node.IsEmpty)) 
     { 
      var text = GetText(hashElement.PreviousNode); 
      if (text != null) 
       colors.Add(new Text(text)); 
      colors.Add(new Text(hashElement.Value.Trim(), hashElement.Name.ToString())); 
     } 

     // handle trailing content 
     var lastText = GetText(doc.Descendants().Last().NextNode); 
     if (lastText != null) 
      colors.Add(new Text(lastText)); 

     // print 
     foreach (var color in colors) 
      Console.WriteLine($"{color.Color}: {color.Content}"); 
    } 

    private static string GetText(XNode node)=> (node as XText)?.Value.Trim(); 

    public class Text 
    { 
     public string Content { get; set; } 
     public string Color { get; set; } 

     public Text(string content, string color = "Black") 
     { 
      Color = color; 
      Content = content; 
     } 
    } 
} 

выход

Black: Hello World 
Red: This is some red text 
Black: This is normal 
Blue: This is blue text 

предостережение: Любая помощь приветствуется. Мой Linq-to-xml может быть немного ржавым.

+0

Эй, спасибо за ответ. К сожалению, это не xml, с которым я имею дело, это просто простая строка, переданная в метод (из lua в этом случае, но я не думаю, что это важно) – Ben

+0

@ user1412240 вы можете легко сделать xml: '@" "+ response +" ";' – aloisdg

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