使用或不使用正则表达式在 C# 中查找和替换多个字符串
Find and Replace multiple strings in c# with or without regex
我的代码需要一些帮助。我想做的是在一个句子中一次找到一个字符串,然后用 span 标记替换相同的字符串。
我用 javascript 取得了同样的成绩,但我不确定如何在 C#
中做到这一点
js 中的代码:
//this function takes 'buffer' as content &
//search query (multiple string values) as replaceStrings and highlights the query
function highlitor(buffer, replaceStrings)
{
var highlightedText = buffer;
for (var i = 0; i < replaceStrings.length; i++)
{
var exp = new RegExp("(" + replaceStrings[i] + ")", "gi");
highlightedText = highlightedText.replace(exp, "<span class='highlight-search-text'></span>");
}
return highlightedText;
}
例如
buffer=" This is an exciting and enhansive test" replaceStrings=[exciting,enhace];
highlightedText="This is an <span class='highlight-text'>exciting</span> and <span class='highlight-text'>enhansive</span> test"
提前致谢。
我想你只需要 String.Replace
循环:
public static string Highlitor(string text, IEnumerable<string> replaceStrings)
{
string result = text;
foreach(string repl in replaceStrings.Distinct())
{
string replWith = string.Format("<span class='highlight-text'>{0}</span>", repl);
result = result.Replace(repl, replWith);
}
return result;
}
如果列表不包含重复项,则不需要 Distinct
。
更新:看起来事情要复杂得多。当模式是最终替换字符串的一部分时,您希望通过保留原始大小写来替换部分。
这是我上述方法的修改版本,它使用 String.Replace
的扩展版本:
public static string Highlitor(string text, IEnumerable<string> replaceStrings)
{
string result = text;
foreach (string repl in replaceStrings.Distinct())
{
string replWith = string.Format("<span class='highlight-text'>{0}</span>", repl);
result = ReplaceCaseInsensitive(result, repl, replWith, true);
}
return result;
}
这里是字符串替换不区分大小写的方法,支持保持原大小写:
public static string ReplaceCaseInsensitive(string original, string pattern, string replacement, bool keepOriginalCase = false)
{
int count, position0, position1;
count = position0 = position1 = 0;
int replacementIndexOfPattern = replacement.IndexOf(pattern, StringComparison.OrdinalIgnoreCase);
if (replacementIndexOfPattern == -1)
keepOriginalCase = false; // not necessary
int inc = (original.Length / pattern.Length) *
(replacement.Length - pattern.Length);
char[] chars = new char[original.Length + Math.Max(0, inc)];
bool[] upperCaseLookup = new bool[pattern.Length];
while ((position1 = original.IndexOf(pattern, position0, StringComparison.OrdinalIgnoreCase)) != -1)
{
// first part that will not be replaced
for (int i = position0; i < position1; ++i)
chars[count++] = original[i];
// remember the case of each letter in the found patter that will be replaced
if (keepOriginalCase)
{
for (int i = 0; i < pattern.Length; ++i)
upperCaseLookup[i] = Char.IsUpper(original[position1 + i]);
}
// The part that will be replaced:
for (int i = 0; i < replacement.Length; ++i)
{
// only keep case of the relevant part of the replacement that contains the part to be replaced
bool lookupCase = keepOriginalCase
&& i >= replacementIndexOfPattern
&& i < replacementIndexOfPattern + pattern.Length;
char newChar = replacement[i];
if (lookupCase)
{
bool wasUpper = upperCaseLookup[i - replacementIndexOfPattern];
bool isUpper = Char.IsUpper(newChar);
if (wasUpper && !isUpper)
newChar = Char.ToUpperInvariant(newChar);
else if (!wasUpper && isUpper)
newChar = Char.ToLowerInvariant(newChar);
}
else
{
newChar = replacement[i];
}
chars[count++] = newChar;
}
position0 = position1 + pattern.Length;
}
if (position0 == 0)
return original;
// the rest
for (int i = position0; i < original.Length; ++i)
chars[count++] = original[i];
return new string(chars, 0, count);
}
我获得了以下功能:
for (var j = 0; j < searchTermArray.Length; j++)
{
CompareInfo ci = CultureInfo.CurrentCulture.CompareInfo;
int indexOfTerm = ci.IndexOf(text, searchTermArray[j], CompareOptions.IgnoreCase);
//dont replace if there is no search term in text
if(indexOfTerm!= -1)
{
string subStringToHighlight = text.Substring(indexOfTerm, searchTermArray[j].Length);
//replacing with span
string replaceWith = string.Format("<span class='highlight-search-text'>{0}</span>", subStringToHighlight);
text = Regex.Replace(text, searchTermArray[j], replaceWith, RegexOptions.IgnoreCase);
}
}
我的代码需要一些帮助。我想做的是在一个句子中一次找到一个字符串,然后用 span 标记替换相同的字符串。
我用 javascript 取得了同样的成绩,但我不确定如何在 C#
中做到这一点js 中的代码:
//this function takes 'buffer' as content &
//search query (multiple string values) as replaceStrings and highlights the query
function highlitor(buffer, replaceStrings)
{
var highlightedText = buffer;
for (var i = 0; i < replaceStrings.length; i++)
{
var exp = new RegExp("(" + replaceStrings[i] + ")", "gi");
highlightedText = highlightedText.replace(exp, "<span class='highlight-search-text'></span>");
}
return highlightedText;
}
例如
buffer=" This is an exciting and enhansive test" replaceStrings=[exciting,enhace];
highlightedText="This is an <span class='highlight-text'>exciting</span> and <span class='highlight-text'>enhansive</span> test"
提前致谢。
我想你只需要 String.Replace
循环:
public static string Highlitor(string text, IEnumerable<string> replaceStrings)
{
string result = text;
foreach(string repl in replaceStrings.Distinct())
{
string replWith = string.Format("<span class='highlight-text'>{0}</span>", repl);
result = result.Replace(repl, replWith);
}
return result;
}
如果列表不包含重复项,则不需要 Distinct
。
更新:看起来事情要复杂得多。当模式是最终替换字符串的一部分时,您希望通过保留原始大小写来替换部分。
这是我上述方法的修改版本,它使用 String.Replace
的扩展版本:
public static string Highlitor(string text, IEnumerable<string> replaceStrings)
{
string result = text;
foreach (string repl in replaceStrings.Distinct())
{
string replWith = string.Format("<span class='highlight-text'>{0}</span>", repl);
result = ReplaceCaseInsensitive(result, repl, replWith, true);
}
return result;
}
这里是字符串替换不区分大小写的方法,支持保持原大小写:
public static string ReplaceCaseInsensitive(string original, string pattern, string replacement, bool keepOriginalCase = false)
{
int count, position0, position1;
count = position0 = position1 = 0;
int replacementIndexOfPattern = replacement.IndexOf(pattern, StringComparison.OrdinalIgnoreCase);
if (replacementIndexOfPattern == -1)
keepOriginalCase = false; // not necessary
int inc = (original.Length / pattern.Length) *
(replacement.Length - pattern.Length);
char[] chars = new char[original.Length + Math.Max(0, inc)];
bool[] upperCaseLookup = new bool[pattern.Length];
while ((position1 = original.IndexOf(pattern, position0, StringComparison.OrdinalIgnoreCase)) != -1)
{
// first part that will not be replaced
for (int i = position0; i < position1; ++i)
chars[count++] = original[i];
// remember the case of each letter in the found patter that will be replaced
if (keepOriginalCase)
{
for (int i = 0; i < pattern.Length; ++i)
upperCaseLookup[i] = Char.IsUpper(original[position1 + i]);
}
// The part that will be replaced:
for (int i = 0; i < replacement.Length; ++i)
{
// only keep case of the relevant part of the replacement that contains the part to be replaced
bool lookupCase = keepOriginalCase
&& i >= replacementIndexOfPattern
&& i < replacementIndexOfPattern + pattern.Length;
char newChar = replacement[i];
if (lookupCase)
{
bool wasUpper = upperCaseLookup[i - replacementIndexOfPattern];
bool isUpper = Char.IsUpper(newChar);
if (wasUpper && !isUpper)
newChar = Char.ToUpperInvariant(newChar);
else if (!wasUpper && isUpper)
newChar = Char.ToLowerInvariant(newChar);
}
else
{
newChar = replacement[i];
}
chars[count++] = newChar;
}
position0 = position1 + pattern.Length;
}
if (position0 == 0)
return original;
// the rest
for (int i = position0; i < original.Length; ++i)
chars[count++] = original[i];
return new string(chars, 0, count);
}
我获得了以下功能:
for (var j = 0; j < searchTermArray.Length; j++)
{
CompareInfo ci = CultureInfo.CurrentCulture.CompareInfo;
int indexOfTerm = ci.IndexOf(text, searchTermArray[j], CompareOptions.IgnoreCase);
//dont replace if there is no search term in text
if(indexOfTerm!= -1)
{
string subStringToHighlight = text.Substring(indexOfTerm, searchTermArray[j].Length);
//replacing with span
string replaceWith = string.Format("<span class='highlight-search-text'>{0}</span>", subStringToHighlight);
text = Regex.Replace(text, searchTermArray[j], replaceWith, RegexOptions.IgnoreCase);
}
}