使用正则表达式,匹配一个字符串,然后从匹配中拉出整数值

时间:2014-02-10 15:58:45

标签: c# regex

我想:

  1. 匹配给定的输入,如果它具有[ process id N ],其中N可以是任何整数值(实际上是正值)。
  2. 从匹配中返回N整数值。
  3. 以下似乎适用于两阶段调用但是(应该)是一种既能匹配字符串又能在一次调用中将整数拉出到正则表达式的方法?

    using System;
    using System.Text.RegularExpressions;
    
    namespace ConsoleApplication25
    {
        class Program
        {
            static void Main()
            {
                string instanceName = "message read rate [ process id 1776 ]";
    
                Regex expression = new Regex(@".*process id (\d).*");
                var matches = expression.Match(instanceName);
    
                string processId = Regex.Match(matches.Value, @"\d+").Value;
    
                Console.WriteLine(processId);
            }
        }
    }
    

6 个答案:

答案 0 :(得分:3)

如果你关心性能并且你的输入字符串很大,你会想要在开始和结束时删除你在正则表达式中使用的.*,因为它们实际上没有任何用处。

其次,您当然可以在第一个正则表达式中使用(\d+)来获取进程ID中的所有数字,而不是使用(\d)的单个数字(正如几个已经提到的那样)。然后,您可以通过matches.Groups[1].Value访问它。

最后,如果您使用if (matches.Success)会更安全,只是在没有匹配时不会出错:

using System;
using System.Text.RegularExpressions;

namespace ConsoleApplication25
{
    class Program
    {
        static void Main()
        {
            string instanceName = "message read rate [ process id 1776 ]";

            Regex expression = new Regex(@"process id (\d+)");
            var matches = expression.Match(instanceName);

            if (matches.Success)
            {
                Console.WriteLine("Process ID: " + matches.Groups[1].Value);
            }
            else
            {
                Console.WriteLine("No match found");
            } 
        }
    }
}

至于为什么删除.*会降低正则表达式的效率,您可能希望阅读贪心量词和回溯。简单来说,.*将匹配所有内容直到字符串结尾(除了换行符,除非DOTALL标志处于活动状态,它将能够更多地匹配并进一步降低效率)然后将返回一次一个字符,以获得正则表达式中的其他匹配。字符串中的字符越多,它就越慢,因为要回溯的次数越多。

.Match函数不需要匹配整个字符串;它会在字符串中的任何地方找到匹配项。

答案 1 :(得分:2)

var match = expression.Match(instanceName);
var processId = Int32.Parse(match.Groups[1].Value);

答案 2 :(得分:2)

这样做:

    string instanceName = "message read rate [ process id 1776 ]";
    var s = Regex.Match(instanceName, @".*process id (\d+).*");
    Console.WriteLine(s.Groups[1]);

而不是:

string instanceName = "message read rate [ process id 1776 ]";

            Regex expression = new Regex(@".*process id (\d).*");
            var matches = expression.Match(instanceName);

            string processId = Regex.Match(matches.Value, @"\d+").Value;

            Console.WriteLine(processId);

答案 3 :(得分:2)

虽然有关使用群组的答案是正确的,但我更喜欢使用命名群组。对于您的示例,它可能过度,但是当您开始使用更复杂的正则表达式时,更容易跟踪各个组的内容:

    string instanceName = "message read rate [ process id 1776 ]";
    string expression = @".*process id (?<PROCESS_ID>\d+).*";

    Match match = Regex.Match(instanceName, expression);
    if (match.Success)
    {
        string processId = match.Groups["PROCESS_ID"].Value.Trim();
        Console.WriteLine("Process ID is {0}", processId);
    }
    else
    {
        Console.WriteLine("Could not find process id");
    }

答案 4 :(得分:1)

将正则表达式更改为此

(?<=process id )\d+

这将仅匹配id号

答案 5 :(得分:0)

没有。正则表达式用于搜索文本,解析数字是由你自己完成的。

对于downvoter:问题不是如何使用正则表达式提取数字,而是如何通过正则表达式引擎直接提取数字,这是不可实现的。