Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何访问.NET正则表达式中的命名捕获组?_C#_.net_Regex - Fatal编程技术网

C# 如何访问.NET正则表达式中的命名捕获组?

C# 如何访问.NET正则表达式中的命名捕获组?,c#,.net,regex,C#,.net,Regex,我很难找到一个好的资源来解释如何在C#中使用命名捕获组。这是我目前掌握的代码: string page = Encoding.ASCII.GetString(bytePage); Regex qariRegex = new Regex("<td><a href=\"(?<link>.*?)\">(?<name>.*?)</a></td>"); MatchCollection mc = qariRegex.Matches(pa

我很难找到一个好的资源来解释如何在C#中使用命名捕获组。这是我目前掌握的代码:

string page = Encoding.ASCII.GetString(bytePage);
Regex qariRegex = new Regex("<td><a href=\"(?<link>.*?)\">(?<name>.*?)</a></td>");
MatchCollection mc = qariRegex.Matches(page);
CaptureCollection cc = mc[0].Captures;
MessageBox.Show(cc[0].ToString());
string page=Encoding.ASCII.GetString(bytePage);
正则表达式qariRegex=新正则表达式(“”);
MatchCollection mc=qariRegex.Matches(第页);
CaptureCollection cc=mc[0]。捕获;
Show(cc[0].ToString());
但是,这始终只显示了完整的行:

<td><a href="/path/to/file">Name of File</a></td> 

我在不同的网站上找到了几种其他的“方法”,但我一直得到同样的结果


如何访问在我的正则表达式中指定的命名捕获组?

使用匹配对象的组集合,使用捕获组名称对其进行索引,例如

foreach (Match m in mc){
    MessageBox.Show(m.Groups["link"].Value);
}

通过将命名的捕获组字符串传递给结果
Match
对象的
Groups
属性的索引器,可以指定该字符串

下面是一个小例子:

using System;
using System.Text.RegularExpressions;

class Program
{
    static void Main()
    {
        String sample = "hello-world-";
        Regex regex = new Regex("-(?<test>[^-]*)-");

        Match match = regex.Match(sample);

        if (match.Success)
        {
            Console.WriteLine(match.Groups["test"].Value);
        }
    }
}
使用系统;
使用System.Text.RegularExpressions;
班级计划
{
静态void Main()
{
String sample=“hello world-”;
正则表达式正则表达式=新正则表达式(“-(?[^-]*)-”;
匹配=正则表达式匹配(样本);
如果(匹配成功)
{
Console.WriteLine(match.Groups[“test”].Value);
}
}
}

以下代码示例将与模式匹配,即使中间有空格字符。 i、 e:


以及:

<td> <a      href='/path/to/file' >Name of File</a>  </td>

方法返回true或false,具体取决于输入的htmlTd字符串是匹配模式还是匹配否。如果匹配,则out参数分别包含链接和名称

/// <summary>
/// Assigns proper values to link and name, if the htmlId matches the pattern
/// </summary>
/// <returns>true if success, false otherwise</returns>
public static bool TryGetHrefDetails(string htmlTd, out string link, out string name)
{
    link = null;
    name = null;

    string pattern = "<td>\\s*<a\\s*href\\s*=\\s*(?:\"(?<link>[^\"]*)\"|(?<link>\\S+))\\s*>(?<name>.*)\\s*</a>\\s*</td>";

    if (Regex.IsMatch(htmlTd, pattern))
    {
        Regex r = new Regex(pattern,  RegexOptions.IgnoreCase | RegexOptions.Compiled);
        link = r.Match(htmlTd).Result("${link}");
        name = r.Match(htmlTd).Result("${name}");
        return true;
    }
    else
        return false;
}
//
///如果htmlId与模式匹配,则为链接和名称指定适当的值
/// 
///如果成功,则为true,否则为false
公共静态bool TryGetHrefDetails(字符串htmlTd、输出字符串链接、输出字符串名称)
{
link=null;
name=null;
字符串模式=“\\s*\\s*”;
if(Regex.IsMatch(htmlTd,模式))
{
正则表达式r=新正则表达式(模式,RegexOptions.IgnoreCase | RegexOptions.Compiled);
link=r.Match(htmlTd.Result(“${link}”);
name=r.Match(htmlTd.Result(“${name}”);
返回true;
}
其他的
返回false;
}

我已经对此进行了测试,它工作正常。

此外,如果有人在对Regex对象执行搜索之前需要组名,他可以使用:

var regex = new Regex(pattern); // initialized somewhere
// ...
var groupNames = regex.GetGroupNames();
这个答案比其他答案更好,因为它似乎完全解决了问题中详述的确切问题

缺点是效率低下,并且不一致地使用IgnoreCase选项

效率低下的部分是因为正则表达式的构造和执行成本很高,在这种情况下,它可能只构造了一次(调用
regex.IsMatch
只是在幕后再次构造正则表达式)。而
Match
方法只能调用一次并存储在变量中,然后
link
name
应该从该变量调用
Result

IgnoreCase选项仅用于
Match
部分,而不用于
Regex.IsMatch
部分

我还将Regex定义移到了方法之外,以便只构造一次(如果我们使用
RegexOptions.Compiled
选项存储程序集,我认为这是明智的方法)

private static Regex hrefRegex=new Regex(“\\s*\\s*”,RegexOptions.IgnoreCase | RegexOptions.Compiled);
公共静态bool TryGetHrefDetails(字符串htmlTd、输出字符串链接、输出字符串名称)
{
var matches=hrefRegex.Match(htmlTd);
如果(匹配。成功)
{
link=matches.Result(“${link}”);
name=matches.Result(“${name}”);
返回true;
}
其他的
{
link=null;
name=null;
返回false;
}
}

Backreference的格式应该是(?.*),而不是(?.*):仅供参考:如果您试图在xml文件中存储命名的捕获组,则
将破坏它。在这种情况下,您可以使用
(?'link.*)
。与这个问题不完全相关,但我是通过谷歌搜索“.net命名的捕获组”登陆这里的,所以我相信其他人也一样…StackOverflow链接,有一个很好的例子:@rtpHarry,不,
不会破坏它。我可以使用
myRegex.GetGroupNames()
集合作为XML元素名称。不要使用
var m
,因为那将是一个
对象
。感谢您提醒我花括号可以访问这些组。我更愿意坚持使用
${1}
来使事情更简单。这完全回答了问题,但有些问题太长,无法在这里解释,但我在中解释并更正了这些问题
var regex = new Regex(pattern); // initialized somewhere
// ...
var groupNames = regex.GetGroupNames();
private static Regex hrefRegex = new Regex("<td>\\s*<a\\s*href\\s*=\\s*(?:\"(?<link>[^\"]*)\"|(?<link>\\S+))\\s*>(?<name>.*)\\s*</a>\\s*</td>",  RegexOptions.IgnoreCase | RegexOptions.Compiled);

public static bool TryGetHrefDetails(string htmlTd, out string link, out string name)
{
    var matches = hrefRegex.Match(htmlTd);
    if (matches.Success)
    {
        link = matches.Result("${link}");
        name = matches.Result("${name}");
        return true;
    }
    else
    {
        link = null;
        name = null;
        return false;
    }
}