如何使用Regex从字符串中提取特定值?

时间:2018-04-14 10:32:41

标签: c# regex string visual-studio

我是Regex的新手,我想从字符串中提取特定值,我有类似的字符串:

"20098: Blue Quest"
"95: Internal Comp"
"33: ICE"

依此类推。每个字符串都有相同的模式:Number后跟":"然后是空格和随机文本。我想在开始时获取数字:"20098","95","33" etc.

我试过

Regex ex = new regex(@"[0-9]+\: [a-zA-Z]$")

这不是给我任何解决方案,我哪里错了? (我正在使用c#)

5 个答案:

答案 0 :(得分:1)

这是一个完全愚蠢的解决方案。但是,我决定在答案中对其他正则表达式和int解析解决方案进行基准测试未经检查的指针版本。

你提到字符串总是格式相同,所以我决定看看它能有多快得到它。

<强> Yehaa

public unsafe static int? FindInt(string val)
{
   var result = 0;
   fixed (char* p = val)
   {
      for (var i = 0; i < val.Length; i++)
      {
         if (*p == ':')return result;
         result = result * 10 + *p - 48;
      }

      return null;
   }
}

我通过100,000次比较分别运行50次测试,分别使用Lee Gunn int.parse进行1,000,000次测试,第4次鸟类^\d+(?=: [A-Z])也是我的指针版本和^\d+

<强>结果

Test Framework : .NET Framework 4.7.1

Scale : 100000
Name                   |       Time |      Delta |  Deviation |       Cycles
----------------------------------------------------------------------------
Pointers               |   2.597 ms |   0.144 ms |       0.19 |    8,836,015
Int.Parse              |  17.111 ms |   1.009 ms |       2.91 |   57,167,918
Regex ^\d+             |  85.564 ms |  10.957 ms |       6.14 |  290,724,120
Regex ^\d+(?=: [A-Z])  |  98.912 ms |   1.508 ms |       7.16 |  336,716,453


Scale : 1000000
Name                   |        Time |      Delta |  Deviation |         Cycles
-------------------------------------------------------------------------------
Pointers               |   25.968 ms |   1.150 ms |       1.15 |     88,395,856
Int.Parse              |  143.382 ms |   2.536 ms |       2.62 |    487,929,382
Regex ^\d+             |  847.109 ms |  14.375 ms |      21.92 |  2,880,964,856
Regex ^\d+(?=: [A-Z])  |  950.591 ms |   6.281 ms |      20.38 |  3,235,489,411

不出所料,正则表达糟透了

答案 1 :(得分:0)

如果它们都是单独的字符串 - 您不需要使用正则表达式,您只需使用:

editText.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        //Check your criteria for smiley face using CharSequence s
    }

    @Override
    public void afterTextChanged(Editable s) {

    }
});

如果他们全部包含在一个刺痛中,您可以遍历每一行并执行var s = "20098: Blue Quest"; var index = s.IndexOf(':'); if(index > 0){ if(int.TryParse(s.Substring(0, index), out var number)) { // Do stuff } } 。也许有点容易阅读,因为很多人对正则表达式感到不舒服。

答案 2 :(得分:0)

在正则表达式"[0-9]+: [a-zA-Z]$中,您匹配一个或多个数字,后跟冒号,然后是单个小写或大写字符。 这将匹配20098: B并且仅与数字不匹配。

除了使用正如建议的正则表达式之外,还有更好的选择,但您可以从字符串^的开头匹配一个或多个数字\d+,并使用正向前瞻(?=来断言接下来是冒号,空格和大写字符[A-Z])

^\d+(?=: [A-Z])

答案 3 :(得分:-1)

首先,在结肠之后,yoiu应该使用\ s而不是文字空间。此外,如果冒号后的文本可以包含空格,则第二组也应该允许/ s并在其后面加上+。

[0-9]+\:\s[a-zA-Z\s]+$

其次,整个正则表达式将返回整个字符串。如果你只想要第一个数字,那么正则表达式就是:

[0-9]+

答案 4 :(得分:-1)

您可以使用look-behind ?<=查找^"之后的任何数字(其中^是行的开头):

(?<=^")[0-9]+