2011-10-06 5 views
2

+-&|!(){}[]^"~*?:\ 문자 앞에 \\을 붙임으로써이 문자를 이스케이프 처리해야합니다. 이 작업을 수행하는 가장 좋은 방법은 무엇입니까? 내 첫 번째 생각은 대체를 사용하지만, 그것은 교체 할 각 항목에 대한 문자열을 검색합니다. 나는 한 번에 모든 것을 얻을 수있는 정규 표현식으로 그것을 할 수있는 방법이 있어야한다고 생각합니다.문자를 이스케이프하는 최적의 방법

+0

참조하십시오이 질문을 참조하십시오 : http://stackoverflow.com/questions/323640/can-i-convert-ac-string-value-to-an-escaped-string-를 리터럴 –

답변

6

그것은 정규 표현식 가능 :

이런 식으로 뭔가 (input은 문자열입니다). 가장 까다로운 부분은 제대로 백 슬래시 지옥으로받지 않고 특수 문자를 탈출한다 :

s = Regex.Replace(s, @"[+\-&|!(){}[\]^""~*?:\\]", "\\$0"); 

StringBuilder 솔루션 mentioned by Eric J. 간단하고 아주 우아한.

StringBuilder sb = new StringBuilder(); 
foreach (char c in s) 
{ 
    if ("+-&|!(){}[]^\"~*?:\\".Contains(c)) 
    { 
     sb.Append('\\'); 
    } 
    sb.Append(c); 
} 
s = sb.ToString(); 
+0

문자열 생성기 솔루션의 경우 – Jamiec

+0

문자열이 모두 큰 경우 초기 크기를 제공하고 원래 문자열보다 약간 큰 값으로 설정할 수있는 StringBuilder 생성자를 사용합니다. –

0

확실하게 정규식 (정규식)을 사용하는 가장 좋은 방법입니다!

\+\-\&\|\!\(\)\{\}\[\]\^\"\~\*\?\:\\ 
+1

왜? RegEx는 편리하지만 상당히 느릴 수 있습니다. 실제로 .NET 4.5의 몇 가지 주요 기능 향상 중 하나는 정규 표현식의 실행 시간을 제한하는 것입니다. http://en.wikipedia.org/wiki/.NET_Framework_version_history#Common_Language_Runtime_.28CLR.29 –

4

아마 정규식보다 더 나은 옵션이 될 것 모두 StringBuilder를 사용 :

string str = @"+-&|!(){}[]^""~*?:\"; 
string pattern = @"(\+|\-|\&|\||\!|\(|\)|\{|\}|\[|\]|\^|\""|\~|\*|\?|\:|\\)"; 
string output = Regex.Replace(str, pattern, @"\$1"); 

다음과 같은 출력을 제공합니다. Regex.Replace vs String.Replace vs StringBuilder.Replace

public const string CharsToBeEscaped = "+-&|!(){}[]^\"~*?:\\'"; 

string s = "+-&|!(){}[]^\"~*?:\\"; 

StringBuilder sb = new StringBuilder(); 
sb.Append(s); 

for (int i = 0; i < CharsToBeEscaped.Length; i++) { 
    sb.Replace(CharsToBeEscaped.Substring(i,1), @"\" + CharsToBeEscaped[i]); 
} 
sb.Replace(@"\\", @"\"); 

s = sb.ToString(); 
+0

+ ½ StringBuilder를 제안합니다. 그러나, 당신의 기사를 보면서 나는 그것이 나의 대답에있는 코드와 약간 다른 접근법을 보여줄 것이라고 생각한다. 나는 그것이 효율적이지는 않지만 확실하지 않다고 생각한다. 또한이 기사를 읽기가 어렵다고 생각합니다. 당신이 사용할 코드를 게시 할 수 있습니까? 어쨌든 나는 다른 질문에 대한 답 중 하나를 upvoted. :) –

+0

@ MarkByers 여기 내 구현이 될 것입니다. –

+0

+1을 제공합니다. 나는 여전히 내 코드에 비해 성능에 대해 조금 염려하고있다 ... 나는 그것을 테스트하지는 않았지만, 이것은 반복 된 대체로 인해 느린 것으로 생각한다. 그리고 버그가 있습니다. 왜냐하면 먼저 특수 문자를 백 슬래시로 이스케이프 처리하고 나중에 백 슬래시를 이스케이프 처리하기 때문에 다른 백 슬래시가 있습니다. –

0

면책 조항 :이 예를 들어 (응용 프로그램에 대한 성능 문제가 발생할 경우이 경우, 정규식을 사용하여 하지에 대한 다른 답변에서 인수를 읽어 마십시오 여기에 아이디어를 지원하는 MSDN의 게시물입니다 이스케이프 가능한 캐릭터의 인스턴스가 많은 매우 큰 문자열). 그러나 정규식이 선택 사항이라면 1 줄의 코드에서이를 수행하는 방법을 아래에서 설명합니다.

귀하가 찾고있는 Regex.Replace 검색하는 정규 표현식 인 입력과 일치 할 때마다 실행되는 MatchEvaluator을 제공합니다. 귀하의 경우에는 단지 String.Concat(@"\",match.Value)을 반환하십시오.

var replaced = Regex.Replace(input, //your string 
     @"[\+\-&|!]", // partial regex to give you an idea 
     match => String.Concat(@"\",match.Value)); //MatchEvaluator, runs for each capture 
1

문자열마다하려면 string.replace()는 원래 문자열의 새로운 수정 복사본을 만드는 것을 의미, C#에서 불변 : 여기를 코딩하는 방법 중 하나입니다.

정말 많은 문제가없는 많은 응용 프로그램의 경우. 당신이 그것에 대해 묻기 때문에, 나는 그것이 당신의 경우에 있다고 생각합니다.

가장 효율적인 방법은 아마도 StringBuilder를 사용하여 수정 된 문자열을 작성하는 것입니다. 소스 문자열을 한 번 반복하고 각 문자열 위치에 문자를 추가하거나 적용 가능한 경우 이스케이프 된 버전을 추가하십시오. StringBuilder constructor을 사용하면 초기 내부 버퍼 크기가 원본 문자열보다 약간 더 크게 할당됩니다.

대부분의 다른 대답이 언급하는 RegEx는이 특정 응용 프로그램에 매우 효율적이며 코드가 적을 것입니다. 그러나 RegEx는 본질적으로 일반화 된 구문 분석 논리를 적용해야하므로 특정 요구에 맞춘 솔루션만큼 빠를 수 없습니다. 또한 어떤 경우에는 RegEx가 매우 느릴 수 있습니다.

http://en.wikipedia.org/wiki/.NET_Framework_version_history#Common_Language_Runtime_.28CLR.29

http://www.codinghorror.com/blog/2006/01/regex-performance.html

+0

사소한 질문. StringBuilder의 용량에 대한 설명은 정확하지 않습니다. .NET 3.5 및 이전 버전에서는 용량이 항상 2^n이었습니다. 그래서 그것은 소스 문자열과 정확하게 같고 소스 문자열의 거의 두 배에 이릅니다. 4.0에서는 용량이 소스 문자열과 동일합니다. (두 분당 용량 = 16). –

관련 문제