私はこれを持っている方法が必要です:
"test, and test but not testing. But yes to test".Replace("test", "text")
これを返す:
"text, and text but not testing. But yes to text"
基本的に、単語全体を置き換えたいのですが、部分一致は置き換えません。
注:このためにVB(SSRS 2008コード)を使用する必要がありますが、C#は私の通常の言語なので、どちらの応答も問題ありません。
正規表現は最も簡単なアプローチです。
string input = "test, and test but not testing. But yes to test";
string pattern = @"\btest\b";
string replace = "text";
string result = Regex.Replace(input, pattern, replace);
Console.WriteLine(result);
パターンの重要な部分は\b
メタキャラクターで、Wordの境界で一致します。大文字と小文字を区別しないようにする必要がある場合は、RegexOptions.IgnoreCase
を使用します。
Regex.Replace(input, pattern, replace, RegexOptions.IgnoreCase);
Ahmad Mageed によって提案された正規表現をラップする関数( ブログの投稿 を参照)を作成しました
/// <summary>
/// Uses regex '\b' as suggested in https://stackoverflow.com/questions/6143642/way-to-have-string-replace-only-hit-whole-words
/// </summary>
/// <param name="original"></param>
/// <param name="wordToFind"></param>
/// <param name="replacement"></param>
/// <param name="regexOptions"></param>
/// <returns></returns>
static public string ReplaceWholeWord(this string original, string wordToFind, string replacement, RegexOptions regexOptions = RegexOptions.None)
{
string pattern = String.Format(@"\b{0}\b", wordToFind);
string ret=Regex.Replace(original, pattern, replacement, regexOptions);
return ret;
}
Sgaがコメントしたように、正規表現ソリューションは完全ではありません。そして、私もパフォーマンスにやさしいとは思いません。
私の貢献は次のとおりです。
public static class StringExtendsionsMethods
{
public static String ReplaceWholeWord ( this String s, String Word, String bywhat )
{
char firstLetter = Word[0];
StringBuilder sb = new StringBuilder();
bool previousWasLetterOrDigit = false;
int i = 0;
while ( i < s.Length - Word.Length + 1 )
{
bool wordFound = false;
char c = s[i];
if ( c == firstLetter )
if ( ! previousWasLetterOrDigit )
if ( s.Substring ( i, Word.Length ).Equals ( Word ) )
{
wordFound = true;
bool wholeWordFound = true;
if ( s.Length > i + Word.Length )
{
if ( Char.IsLetterOrDigit ( s[i+Word.Length] ) )
wholeWordFound = false;
}
if ( wholeWordFound )
sb.Append ( bywhat );
else
sb.Append ( Word );
i += Word.Length;
}
if ( ! wordFound )
{
previousWasLetterOrDigit = Char.IsLetterOrDigit ( c );
sb.Append ( c );
i++;
}
}
if ( s.Length - i > 0 )
sb.Append ( s.Substring ( i ) );
return sb.ToString ();
}
}
...テストケース付き:
String a = "alpha is alpha";
Console.WriteLine ( a.ReplaceWholeWord ( "alpha", "alphonse" ) );
Console.WriteLine ( a.ReplaceWholeWord ( "alpha", "alf" ) );
a = "alphaisomega";
Console.WriteLine ( a.ReplaceWholeWord ( "alpha", "xxx" ) );
a = "aalpha is alphaa";
Console.WriteLine ( a.ReplaceWholeWord ( "alpha", "xxx" ) );
a = "alpha1/alpha2/alpha3";
Console.WriteLine ( a.ReplaceWholeWord ( "alpha", "xxx" ) );
a = "alpha/alpha/alpha";
Console.WriteLine ( a.ReplaceWholeWord ( "alpha", "alphonse" ) );
この特定の正規表現パターンに関するメモを追加したいだけです(受け入れられた回答とReplaceWholeWord関数の両方で使用されます)。置き換えようとしているものがWordでない場合は機能しません。
ここにテストケース:
using System;
using System.Text.RegularExpressions;
public class Test
{
public static void Main()
{
string input = "doin' some replacement";
string pattern = @"\bdoin'\b";
string replace = "doing";
string result = Regex.Replace(input, pattern, replace);
Console.WriteLine(result);
}
}
(コードを試す準備ができました: http://ideone.com/2Nt0A )
これは、特にバッチ翻訳を行う場合に考慮に入れる必要があります(一部の国際化作業で行ったように)。
Wordを構成する文字、つまり「_」と「@」を定義する場合
あなたは私の(vb.net)関数を使用できます:
Function Replace_Whole_Word(Input As String, Find As String, Replace As String)
Dim Word_Chars As String = "ABCDEFGHIJKLMNOPQRSTUVWYXZabcdefghijklmnopqrstuvwyxz0123456789_@"
Dim Word_Index As Integer = 0
Do Until False
Word_Index = Input.IndexOf(Find, Word_Index)
If Word_Index < 0 Then Exit Do
If Word_Index = 0 OrElse Word_Chars.Contains(Input(Word_Index - 1)) = False Then
If Word_Index + Len(Find) = Input.Length OrElse Word_Chars.Contains(Input(Word_Index + Len(Find))) = False Then
Input = Mid(Input, 1, Word_Index) & Replace & Mid(Input, Word_Index + Len(Find) + 1)
End If
End If
Word_Index = Word_Index + 1
Loop
Return Input
End Function
テスト
Replace_Whole_Word("We need to replace words tonight. Not to_day and not too well to", "to", "xxx")
結果
"We need xxx replace words tonight. Not to_day and not too well xxx"