繁体   English   中英

c#正则表达式匹配示例

[英]c# regex matches example

我正在尝试从以下文本中获取值。 这如何用 Regex 完成?

输入

Lorem ipsum dolor sat %download%#456 amet, consectetur adipiscing %download%#3434 elit。 Duis non nunc nec mauris feugiat porttitor。 sed tincidunt blandit dui a viverra%download%#298。 Aenean dapibus nisl %download%#893434 id nibh auctor vel tempor velit blandit。

输出

456  
3434  
298   
893434 

因此,您试图获取以标记“%download%#”开头的数值?

试试这个模式:

(?<=%download%#)\d+

那应该工作。 我不认为#%是 .NET Regex 中的特殊字符,但是您必须像\\\\一样转义反斜杠,或者对整个模式使用逐字字符串

var regex = new Regex(@"(?<=%download%#)\d+");
return regex.Matches(strInput);

在这里测试: http : //rextester.com/BLYCC16700

注意: lookbehind 断言(?<=...)很重要,因为您不想在结果中包含%download%# ,只包含它后面的数字。 但是,您的示例似乎在您要捕获的每个字符串之前都需要它。 后视组将确保它存在于输入字符串中,但不会将其包含在返回的结果中。 更多关于环视断言的信息在这里。

我看到的所有其他响应都很好,但 C# 支持命名组!

我会使用以下代码:

const string input = "Lorem ipsum dolor sit %download%#456 amet, consectetur adipiscing %download%#3434 elit. Duis non nunc nec mauris feugiat porttitor. Sed tincidunt blandit dui a viverra%download%#298. Aenean dapibus nisl %download%#893434 id nibh auctor vel tempor velit blandit.";

static void Main(string[] args)
{
    Regex expression = new Regex(@"%download%#(?<Identifier>[0-9]*)");
    var results = expression.Matches(input);
    foreach (Match match in results)
    {
        Console.WriteLine(match.Groups["Identifier"].Value);
    }
}

代码如下: (?<Identifier>[0-9]*)指定[0-9]*的结果将是我们如上索引的命名组的一部分: match.Groups["Identifier"].Value

public void match2()
{
    string input = "%download%#893434";
    Regex word = new Regex(@"\d+");
    Match m = word.Match(input);
    Console.WriteLine(m.Value);
}

看起来这里的大部分帖子都描述了你在这里需要的东西。 但是 - 您可能需要更复杂的行为 - 取决于您要解析的内容。 在您的情况下,您可能不需要更复杂的解析 - 但这取决于您要提取的信息。

您可以在类中使用正则表达式组作为字段名称,之后可以这样写:

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

public class Info
{
    public String Identifier;
    public char nextChar;
};

class testRegex {

    const string input = "Lorem ipsum dolor sit %download%#456 amet, consectetur adipiscing %download%#3434 elit. " +
    "Duis non nunc nec mauris feugiat porttitor. Sed tincidunt blandit dui a viverra%download%#298. Aenean dapibus nisl %download%#893434 id nibh auctor vel tempor velit blandit.";

    static void Main(string[] args)
    {
        Regex regex = new Regex(@"%download%#(?<Identifier>[0-9]*)(?<nextChar>.)(?<thisCharIsNotNeeded>.)");
        List<Info> infos = new List<Info>();

        foreach (Match match in regex.Matches(input))
        {
            Info info = new Info();
            for( int i = 1; i < regex.GetGroupNames().Length; i++ )
            {
                String groupName = regex.GetGroupNames()[i];

                FieldInfo fi = info.GetType().GetField(regex.GetGroupNames()[i]);

                if( fi != null ) // Field is non-public or does not exists.
                    fi.SetValue( info, Convert.ChangeType( match.Groups[groupName].Value, fi.FieldType));
            }
            infos.Add(info);
        }

        foreach ( var info in infos )
        {
            Console.WriteLine(info.Identifier + " followed by '" + info.nextChar.ToString() + "'");
        }
    }

};

此机制使用 C# 反射来为类设置值。 组名与类实例中的字段名匹配。 请注意 Convert.ChangeType 不接受任何类型的垃圾。

如果要添加行/列的跟踪 - 您可以为行添加额外的 Regex 拆分,但为了保持 for 循环完整 - 所有匹配模式都必须具有命名组。 (否则列索引会计算错误)

这将导致以下输出:

456 followed by ' '
3434 followed by ' '
298 followed by '.'
893434 followed by ' '
Regex regex = new Regex("%download#(\\d+?)%", RegexOptions.SingleLine);
Matches m = regex.Matches(input);

我认为可以解决问题(未测试)。

这种模式应该有效:

#\d

foreach(var match in System.Text.RegularExpressions.RegEx.Matches(input, "#\d"))
{
    Console.WriteLine(match.Value);
}

(我不在 Visual Studio 前面,但即使它不能按原样编译,它也应该足够接近以调整为有效的东西)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM