2011-12-22 3 views
2

NET 2.0 및 WinForms를 사용하고 있습니다.문자열을 사용하여 전체 단어를 일치 시키십시오.

현재 문자열을 주어진 텍스트에서 다른 것으로 바꾸려면 코드가 필요하지만 텍스트에서는 전체 단어 만 찾아야합니다. 내 말은있다 : 즉 전체 단어이기 때문에 그것은 단지, COUNTCOUNTER의 첫 번째 인스턴스를 교체해야

string name = @"COUNTER = $40 
CLOCK_COUNTER = $60"; 
name = name.Replace("COUNTER", "COUNT"); 

. 그러나 string.Replace은 전체 단어를 고려하지 않습니다.

정규식을 사용하지 않는 것이 좋습니다. 나는 이미 그것을 시도하고, 나의 필요를 위해 너무 느리다. 나는 매우 빠르고 효율적인 것을 필요로한다. 내가 어떻게 이걸 이룰 수 있니?

+8

죄송합니다 봉오리, 그것은 정규식 또는 아무것도 : -----------------

나는 당신의 요구에 맞게 일이 문서에 대한 기억. – rfmodulator

+6

"정규식을 권장하지 마십시오." 정규식이 느려지지만 문자열이되는 상황은 정확히 무엇입니까? 바꾸기가 허용됩니까? 당신은 string.Replace가 그것을 어떻게하는지 이해합니다. 그리고 그것이 의미하는 기억 사용법은 마술입니까? – asawyer

+0

@codeparkle - CLOCK_COUNTER 뒤에는 공백이 있지만 다른 접두사는 있습니다. 그래서 "단어"는 "개행 전후의 개행"으로 정의된다고 생각합니다. – Matten

답변

7
string input = @"COUNTER = $40 
CLOCK_COUNTER = $60"; 

string name = Regex.Replace(input, @"\bCOUNTER\b", "COUNT"); 

\b 마크 워드 경계를 표시합니다.


자신 만의 알고리즘을 개발할 수있는 유일한 방법은 Regex입니다. "COUNTER"를 검색하여 단어 문자가 아닌 이전 문자와 다음 문자를 테스트하십시오.


편집 :

public static class ReplaceWordNoRegex 
{ 
    private static bool IsWordChar(char c) 
    { 
     return Char.IsLetterOrDigit(c) || c == '_'; 
    } 

    public static string ReplaceFullWords(this string s, string oldWord, string newWord) 
    { 
     if (s == null) { 
      return null; 
     } 
     int startIndex = 0; 
     while (true) { 
      int position = s.IndexOf(oldWord, startIndex); 
      if (position == -1) { 
       return s; 
      } 
      int indexAfter = position + oldWord.Length; 
      if ((position == 0 || !IsWordChar(s[position - 1])) && (indexAfter == s.Length || !IsWordChar(s[indexAfter]))) { 
       s = s.Substring(0, position) + newWord + s.Substring(indexAfter); 
       startIndex = position + newWord.Length; 
      } else { 
       startIndex = position + oldWord.Length; 
      } 
     } 
    } 
} 

편집 # 2 : 여기 그리고이 모두 StringBuilder와 솔루션 여기서 확장 방법으로 내 솔루션은

입니다.

public static string ReplaceFullWords(this string s, string oldWord, string newWord) 
{ 
    if (s == null) { 
     return null; 
    } 
    int startIndex = 0; // Where we start to search in s. 
    int copyPos = 0; // Where we start to copy from s to sb. 
    var sb = new StringBuilder(); 
    while (true) { 
     int position = s.IndexOf(oldWord, startIndex); 
     if (position == -1) { 
      if (copyPos == 0) { 
       return s; 
      } 
      if (s.Length > copyPos) { // Copy last chunk. 
       sb.Append(s.Substring(copyPos, s.Length - copyPos)); 
      } 
      return sb.ToString(); 
     } 
     int indexAfter = position + oldWord.Length; 
     if ((position == 0 || !IsWordChar(s[position - 1])) && (indexAfter == s.Length || !IsWordChar(s[indexAfter]))) { 
      sb.Append(s.Substring(copyPos, position - copyPos)).Append(newWord); 
      copyPos = position + oldWord.Length; 
     } 
     startIndex = position + oldWord.Length; 
    } 
} 
+0

그것이 그가해야 할 일이지만, 그가 요구 한 것에 대해 직접적으로 적용됩니다 (정규식 없음). –

+0

그는 정규 표현식을 사용하고 싶지 않은 이유는 속도를 높이기 위해서이며, 수천 개의 큰 문자열과 여러 개의 대체 문자열을 처리한다고 가정 할 때 여기에 입력 문자열의 길이에 미리 할당 된 문자열 작성기를 사용해야합니다. 자신의 알고리즘을 롤에 넣는다면 효율적으로 처리하는 것이 좋습니다. –

+0

StringBuilder에는'IndexOf()'가 없습니다. 즉, 원래 문자열을 작업하여 위치를 찾고 StringBuilder를 사용하여 새 문자열을 만들어야합니다. 그리 분명하지 않습니다. –

0

작은 해결 방법 :

string name = @"COUNTER = $40 
CLOCK_COUNTER = $60"; 
name=" "+name; 
name = name.Replace(" COUNTER ", " COUNT "); 
당신이 다른 단어를 교체 할 않는 문자의 일종으로 대체하는거야 단어를 표시해야

홈페이지 생각하지 않은

+0

Edge case 지옥에 오신 것을 환영합니다. – asawyer

+0

정규식없이 다른 것을 제안하십시오! – Elastep

+0

앞에 공백이 없기 때문에이 카운터가 COUNTER를 대체하지 않습니까? 당신은'name = ""+ name; "을 의미 했습니까? – Adam

0

나는

 string input = @"COUNTER = $40 CLOCK_COUNTER = $60"; 
     string pattern = @"\bCOUNTER\b"; 
     string replacement = "COUNT"; 
     var regex = new Regex(pattern,RegexOptions.Compiled); 
     string result = regex.Replace(input, replacement); 
정규식

보다는 (내가 시간을 개발에 대해서 이야기하고) 당신이 문자열이 빨리 대체 달성 할 수 있다고 생각

RegexOptions.Compiled를 추가하면 재사용하려는 경우 더 빠릅니다.

------------------- 업데이트 ------------

http://www.codeproject.com/KB/string/fastestcscaseinsstringrep.aspx

+0

기술적으로 당신이 오래된 문자열 교체 알고리즘을 굴려서 새로운 문자열 생성기를 올바른 크기로 할당한다면 그건 사실이 아닙니다. 나는 당신이 훨씬 빠르게 만들 수 있다고 확신합니다. 중요한 점은 거의 가치가 없다는 것입니다. –

+0

예, 동의합니다. "더 빨리"나는 시간을 내주는 것을 의미한다고 이야기하고있었습니다. – giammin

관련 문제