使用 LINQ 在 C# 中提取 startsequence 和 endsequence 之间的子字符串

Extract substring between startsequence and endsequence in C# using LINQ

我有一个包含处理指令的 XML 实例。我想要一个特定的(schematron 声明):

<?xml-model href="../../a/b/c.sch" schematypens="http://purl.oclc.org/dsdl/schematron"?>

存在的可能不止这些处理指令,所以我不能依赖它在 DOM 中的位置;另一方面,保证只有一个(或 none)这样的 Schematron 文件引用。因此,我是这样理解的:

XProcessingInstruction p = d.Nodes().OfType<XProcessingInstruction>()
   .Where(x => x.Target.Equals("xml-model") && 
    x.Data.Contains("schematypens=\"http://purl.oclc.org/dsdl/schematron\""))
   .FirstOrDefault();

在给出的例子中,p.Data的内容是字符串

href="../../a/b/c.sch" schematypens="http://purl.oclc.org/dsdl/schematron"

需要提取通过@href指定的路径(即在这个例子中我想要字符串../../a/b/c.sch没有双引号。换句话说:我需要 href=" 之后和下一个 " 之前的子字符串。我正在尝试使用 LINQ 实现我的目标:

var a = p.Data.Split(' ').Where(s => s.StartsWith("href=\""))
       .Select(s => s.Substring("href=\"".Length))
       .Select(s => s.TakeWhile(c => c != '"'));

我原以为这给了我一个 IEnumerable<char>,然后我可以用 here 中描述的一种方式将其转换为字符串,但事实并非如此:根据 LINQPad,我似乎得到一个 IEnumerabale<IEnumerable<char>>,我无法将其变成一个字符串。

如何使用 LINQ 正确完成此操作?也许我最好在 LINQ 中使用正则表达式?


编辑: 打完这个之后,我想出了一个可行的解决方案,但它看起来很不优雅:

string a = new string
   (
      p.Data.Substring(p.Data.IndexOf("href=\"") + "href=\"".Length)
      .TakeWhile(c => c != '"').ToArray()
   );

什么是更好的方法?

试试这个:

var input = @"<?xml-model href=""../../a/b/c.sch"" schematypens=""http://purl.oclc.org/dsdl/schematron""?>";
var match = Regex.Match(input, @"href=""(.*?)""");
var url = match.Groups[1].Value;

这给了我 ../../a/b/c.sch url

请不要使用 Regex 进行一般 XML 解析,但对于这种情况没问题。