如何使用正则表达式匹配从 xml 文件中搜索和替换包含占位符标记的文本。 VB.net 或 C#

Posted

技术标签:

【中文标题】如何使用正则表达式匹配从 xml 文件中搜索和替换包含占位符标记的文本。 VB.net 或 C#【英文标题】:How do I search and replace text containing placeholder tokens with a values from an xml file using regular expression matching. VB.net or C# 【发布时间】:2018-05-17 01:00:55 【问题描述】:

我有一个问题需要 vb.net 或 C# 解决方案与正则表达式匹配。 我对正则表达式不太擅长,所以我想我会寻求帮助。 我有一些包含一个或多个标记的文本,我需要用从 xml 文件中检索到的值替换这些标记。令牌是相似的,但有两种不同的类型。对于第一种类型的匹配,我将用 file1.xml 中的值替换,对于第 2 种类型的匹配,我将从 file2.xml 中替换。

可替换标记的格式如下:

类型 1 令牌:&*T1&&*T1001&

类型 2 令牌:&*SomeValue&&*A2ndValue&

类型 1 令牌的替换值在 File1.xml 中,类型 2 令牌的替换值在 File2.xml 中

在上面的示例中,当找到类型 1 (T1000) 的匹配项时,我需要将整个令牌 (&*T1000&) 替换为 File1.xml 中元素 T1000 的值。 <T1000>ValueT1000</T1000>

在 2nd Type 中:当找到 Type 2 (SomeValue) 的匹配项时,我需要将整个令牌 (&*SomeValue&) 替换为 File2.xml 中 Element SomeValue 的值。 <SomeValue>Value2</SomeValue>

输入文本示例: 这是一些带有第一个标记 &T1& 和第二个标记 &*T1001& 以及更多标记 &*SomeValue& 和更多 &*A2ndValue& 的文本。

到目前为止,在 pirs 的代码的帮助下,在 vb.net 中,我有这个:

Public Shared Sub Main()
    Dim pattern As String = "\&\*?([\w]+)\&"
    Dim input As String = "This is some text with first token &*T1& and the second token &*T1001& and more tokens &*SomeValue& and still more &*A2ndValue&."
        For Each m As Match In Regex.Matches(input, pattern)
            Console.WriteLine("'0' found at index 1.", m.Groups(1).Value, m.Index)
        Next
End Sub

返回:

'T1' found at index 35.
'T1001' found at index 62.
'SomeValue' found at index 87.
'A2ndValue' found at index 115

我需要处理此文本并将所有标记替换为从 2 个 xml 文件中检索到的值。 任何帮助表示赞赏。

[编辑] 来自@pirs的回答。也许这样做的方法是首先找到 T1000 类型的匹配项,然后用匹配的正则表达式索引替换。按索引替换时,我想我必须从最后一个索引开始,因为每次替换都会更改匹配的索引。 在替换所有 T1000 匹配项后,我想我可以对上面的输出字符串进行另一个匹配,然后替换所有 2nd 类型的匹配项。

什么是 T1000 的正则表达式匹配(T 后跟任意位数)

【问题讨论】:

你的要求不是很好。无法弄清楚你想要什么,但你不应该用正则表达式来做这件事。使用 XElement 或 XmlElement 有更好的方法。 @jdweng 我编辑并澄清了这个问题。 【参考方案1】:

[EDIT]替换为索引so..

    public static string ReplaceIndex(this string self, string OldString, string newString, int index)        
    
        return self.Remove(index, OldString.Length).Insert(index, newString); 
    
  // ...
  s = s.ReplaceIndex(m.Groups(1).Value, "newString", m.Index)
  // ...

[EDIT]尝试直接替换值

// ...
s = s.Replace(m.Groups(1).Value, "newValue")
// ...

[编辑] &*& 的正则表达式:https://regex101.com/r/MVRS7U/1/

为 c# 生成的正则表达式函数

using System;
using System.Text.RegularExpressions;

public class Example

    public static void Main()
    
        string pattern = @"&\*?([^&\*\d]+)";
        string input = @"&*cool&*it's&working&in&*all&case";

        foreach (Match m in Regex.Matches(input, pattern))
        
            Console.WriteLine("'0' found at index 1.", m.Value, m.Index);
        
    

现在应该没问题了:-)

__

我不确定您到底想要什么,但这里有适合您情况的正则表达式:https://regex101.com/r/5i3RII/1/

在这里,为 c# 生成的正则表达式函数(你应该做一个自定义函数来满足你的需要..):

using System;
using System.Text.RegularExpressions;

public class Example

    public static void Main()
    
        string pattern = @"<[a-zA-Z-0-9]+\s?>([\w]+)<\/[a-zA-Z-0-9]+\s?>";
        // the example you gave
        string input = @"<T1>value1</T1>
            <T1001>value2</T1001>
            <T2000 />
            <SomeValue>value1</SomeValue >
            <A2ndValue>value2</A2ndValue >";

        foreach (Match m in Regex.Matches(input, pattern))
        
            // the output
            Console.WriteLine("'0' found at index 1.", m.Value, m.Index);
        
    

【讨论】:

谢谢。除了要匹配的正则表达式模式之外,您的回答不是 xml。我需要匹配的正则表达式模式是:&*T1& 或 &*T1000& 等。它以 &*T 开头,后跟任意整数,以 & 结尾。找到匹配项后,我需要提取到字符串 T1、T1000 等。在第二种情况下,我需要匹配 &*SomeValue&。正则表达式模式也可以与上述相同。然后我需要知道哪个 m.value 是 Type 1 (T1000),哪个是 Type 2 (SomeValue)。这是因为我的代码将从 File1.xml 中检索 T1000 类型的元素和 File2.xml 中的 SomeValue 类型的元素。 谢谢。除了要匹配的正则表达式模式之外,您的回答不是 xml。我需要匹配的正则表达式模式是:&*T1& 或 &*T1000& 等。它以 &*T 开头,后跟任意整数,以 & 结尾。找到匹配项后,我需要提取到字符串 T1、T1000 等。在第二种情况下,我需要匹配 &*SomeValue&。正则表达式模式也可以与上述相同。然后我需要知道哪个 m.value 是 Type 1 (T1000),哪个是 Type 2 (SomeValue)。这是因为我的代码将从 File1.xml 中检索 T1000 类型的元素和 File2.xml 中的 SomeValue 类型的元素。 我不太明白,你能在你的帖子中添加输入和输出吗?我会做的 这是输入字符串:这是一些带有第一个标记 &*T1& 和第二个标记 &*T1001& 以及更多标记 &*SomeValue& 以及更多 &*A2ndValue& 的文本。我需要获取 &* (开始)和 & (结束)之间的值。然后我需要知道哪个值类似于 T1000(T 后跟一个整数)。对于这种情况,我将在 File1.xml 中检索元素 T1000 的值,否则我将从 File2.xml 中检索元素 SomeValue 的值。 我澄清了这个问题并添加了我的代码(在 pirs 的帮助下。我得到了我需要的匹配项。但是我如何区分这两种类型的令牌。【参考方案2】:

我明白你想做什么。下面的代码可以做所有事情:

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

namespace ConsoleApplication1

    class Program
    
        const string FILENAME = @"c:\temp\text.xml";
        static void Main(string[] args)
        
            string input = "This is some text with first token &*T1& and the second token &*T1001& and more tokens &*SomeValue& and still more &*A2ndValue&.";


            XDocument doc = XDocument.Load(FILENAME);

            string patternToken = "&[^&]+&";
            string patternTag = @"&\*(?'tag'[^&]+)&";

            MatchCollection  matches = Regex.Matches(input, patternToken);
            foreach(Match match in matches.Cast<Match>())
            
                string token = match.Value;
                string tag = Regex.Match(token, patternTag).Groups["tag"].Value;
                string tagValue = doc.Descendants(tag).Select(x => (string)x).FirstOrDefault();
                input = input.Replace(token, tagValue);
            

        
    

【讨论】:

以上是关于如何使用正则表达式匹配从 xml 文件中搜索和替换包含占位符标记的文本。 VB.net 或 C#的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 sed、awk 或 gawk 仅打印匹配的内容?

sql正则匹配连续增加数字

PHP 正则表达式(PCRE)

如何编写正则表达式来查找/替换 HTML 类? [复制]

PHP 正则表达式(PCRE)

LinuxShell——正则表达式