2016-12-19 81 views
4

我想要做的是從字符串解析一些自定義標記,但也獲得未標記的內容。例如,我有以下字符串正則表達式來捕獲標記和未標記的內容

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場比賽,上面這兩個,還有「你好世界」和「這是正常的」。

這是正則表達式可能嗎?

舉一個例子,這是我目前的功能:

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就是一個包含文本和顏色的容器),如果你想嘗試與修修補補XML,你可以嘗試這樣的一個解決方案

+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

。我們將使用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; 
     } 
    } 
} 

輸出

​​

警告:任何幫助是值得歡迎的。我的Linq-to-xml可能有點生疏。

+0

嘿謝謝你的回覆。不幸的是,它不是xml我正在處理它只是一個簡單的字符串傳遞給一個方法(在這種情況下,從盧阿,但我不認爲這很重要) – Ben

+0

@ user1412240你可以很容易地使它成爲一個XML:'@「<? xml version ='1.0'encoding ='utf-8'?>「+ response +」「;' – aloisdg