2009-09-15 85 views
2

我有一個包含400個字符串的列表,全部以「_GONOGO」或「_ALLOC」結尾。當應用程序啓動時,我需要從這些字符串中刪除「_GONOGO」或「_ALLOC」。Regex.Replace比條件語句使用String.Contains要慢很多

我試過這個: 'string blah = Regex.Replace(string,「(_GONOGO | _ALLOC)」,「」));'

但它遠遠超過一個簡單的條件語句這樣的慢:

if (string.Contains("_GONOGO")) 
      // use Substring 
else if (string.Contains("_ALLOC")) 
      // use Substring w/different index 

我是新來的正則表達式,所以我希望有人有更好的解決方案或我做什麼可怕的錯誤。這不是什麼大問題,但將這4條線條件變成一條簡單的正則表達式線條將會很好。

+1

如果你在模式的末尾加上一個'$'錨點,你的正則表達式會有更好的表現嗎? – 2009-09-15 00:36:51

+0

你應該使用'EndsWith'而不是'Contains'。隨着更正確,它更快。 :) – 2009-09-15 00:56:20

回答

8

雖然不是正則表達式,你可以做

string blah = string.Replace("_GONOGO", "").Replace("_ALLOC", ""); 

正則表達式是偉大的複雜表情,但是開銷有時會矯枉過正這樣非常簡單的操作。

+0

謝謝,這很好 - 正則表達式不是我的要求,我只是想要它一行。 – alexD 2009-09-15 00:37:27

4

如果您先編譯正則表達式,則正則表達式替換的運行速度可能會更快。如:

Regex exp = new Regex(
    @"(_GONOGO|_ALLOC)", 
    RegexOptions.Compiled); 

exp.Replace(string, String.Empty); 
+0

另請注意(來自MSDN)「正則表達式類是不可變的(只讀),並且本質上是線程安全的。」您可以創建一次並將其分配給靜態只讀字段。請參閱http://www.acorns.com.au/blog/?p=136 – TrueWill 2009-09-15 01:56:55

+0

並從Atwood檔案庫:http://www.codinghorror.com/blog/archives/000228.html – TrueWill 2009-09-15 01:58:46

3

這是預期的;一般來說,用手操縱字符串比使用正則表達式要快。使用正則表達式涉及將表達式編譯爲正則表達式樹,這需要時間。

如David在他的回答中所描述的,如果您在多個地方使用此正則表達式,則可以使用RegexOptions.Compiled標誌來減少每個匹配的開銷。其他正則表達式專家可能會提供改進表達式的提示。不過,你可能會考慮堅持使用String.Replace。它速度快,可讀性強。

1

如果他們都結束在這些模式中的一個,它可能會以更快的速度下降完全取代和使用:

string result = source.Substring(0, source.LastIndexOf('_')); 
1

如果您有關於您的問題域多的信息,你才能把事情很簡單:

const int AllocLength = 6; 
const int GonogoLength = 7; 
string s = ...; 
if (s[s.Length - 1] == 'C') 
    s = s.Substring(0, s.Length - AllocLength); 
else 
    s = s.Substring(0, s.Length - GonogoLength); 

這在理論上是比Abraham's solution快,但不夠靈活。如果字符串有任何改變的機會,那麼這個字符串會遭受可維護性問題,他不會。