簡體   English   中英

使用Regex解析C#中的字符串

[英]Parse string in C# using Regex

需要解析:

/subscriptions/1234/resourceGroups/5678/providers/BlaBlaBla/workspaces/BluBluBlu

並提取變量:

  • 1234
  • 5678
  • 布拉布拉
  • 藍光藍光

如何使用C#和正則表達式以一種簡潔的方式做到這一點?

單行代碼

var bits = noodly.Split('/');

如果仍然需要正則表達式,並且與其他位置一樣,也可以使用正則表達式,則可以使用Capture Collection

^(?:/[^/]*/([^/]*))+

這些項目在組1的捕獲集合中。

這不是要作為答案,而是給將來的讀者(我很無聊)

正則表達式

return Regex.Matches(input, @"^(?:/[^/]*/([^/]*))+")[0]
            .Groups[1]
            .Captures.Cast<Capture>()
            .Select(m => m.Value)
            .ToArray();

正則表達式編譯

private static readonly Regex regex = new Regex(@"^(?:/[^/]*/([^/]*))+", RegexOptions.Compiled);
...

return regex.Matches(input)[0]
            .Groups[1]
            .Captures.Cast<Capture>()
            .Select(m => m.Value)
            .ToArray();

分裂

return input.Split(new []{'/'}, StringSplitOptions.RemoveEmptyEntries)
            .Skip(1)
            .Where((x, i) => i % 2 == 0)
            .ToArray();

不安全

var list = new List<string>();
var result = string.Empty;

fixed (char* pInput = input)
{
   var plen = pInput + input.Length;
   var toggle = true;

   for (var p = pInput; p < plen; p++)
   {
      if (*p == '/')
      {       
         if (result.Length > 0)
            list.Add(result);
         toggle = !toggle;
         result = string.Empty;
         continue;
      }
      if (toggle)
         result += *p;
   }
}
list.Add(result);
return list.ToArray();

基准測試

----------------------------------------------------------------------------
Mode             : Release (64Bit)
Test Framework   : .NET Framework 4.7.1 (CLR 4.0.30319.42000)
----------------------------------------------------------------------------
Operating System : Microsoft Windows 10 Pro
Version          : 10.0.17134
----------------------------------------------------------------------------
CPU Name         : Intel(R) Core(TM) i7-3770K CPU @ 3.50GHz
Description      : Intel64 Family 6 Model 58 Stepping 9
Cores (Threads)  : 4 (8)      : Architecture  : x64
Clock Speed      : 3901 MHz   : Bus Speed     : 100 MHz
L2Cache          : 1 MB       : L3Cache       : 8 MB
----------------------------------------------------------------------------

結果

--- Random characters -------------------------------------------------------
| Value         |  Average |  Fastest |   Cycles | Garbage | Test |    Gain |
--- Scale 1 -------------------------------------------------- Time 0.152 ---
| unsafe        | 2.131 µs | 1.461 µs | 10.567 K | 0.000 B | Pass | 78.42 % |
| split         | 3.874 µs | 2.922 µs | 16.804 K | 0.000 B | Pass | 60.76 % |
| regexCompiled | 7.313 µs | 5.845 µs | 29.310 K | 0.000 B | Pass | 25.93 % |
| regex         | 9.873 µs | 7.891 µs | 37.800 K | 0.000 B | Base |  0.00 % |
-----------------------------------------------------------------------------

摘要

對反映原始模式的不同字符串組合分別測試了1,000,000次。

不安全是非常荒謬的,不應該使用,正則表達式整潔,拆分也不是太難以理解。 如預期的那樣分裂更快。

但是,正則表達式並沒有我想的那么慢。 最后,它歸結為persoanl性能和您的代碼審閱者。

更新資料

正如sln在評論中正確提到的那樣,應編譯正則表達式以使其成為一個良好的基准。 注意我遺漏了.Groups[1].Captures.Cast<Capture>().Select(m => m.Value).ToArray(); 基本上只是將結果保留為字符串數組以使它們保持相同。

IL的編譯使regex表現良好。

免責聲明 ,我對正則表達式一無所知,並一直使用它

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM