众所周知,开发中不可能一帆风顺,有时,系统自带的方法可能不足以满足我们的需求,这时候就需要我们通过编写一些逻辑算法进行适应。最近做项目的时候,需要做一些数据替换,需求如下:
通过查询,得到如下字符串:
a+Abac+a1+a2+a+b+a+c*a+c,a,ba,u/a
我们的需求是将如上的字符”a“替换为”ok“,一眼看上去,这个简单,c#中有一个Replace,那代码如下了:
string met = "a+Abac+a1+a2+a+b+a+c*a+c,a,ba,u/a";
Console.WriteLine(met.Replace("a","ok"));
然后执行了以后,
仔细一看,怎么是这样的:
我们得到的字符串成了【ok+Abokc+ok1+a2+ok+b+ok+c*ok+c,ok,bok,u/ok】这很明显不是我们想要的,因为C#自带的Replace替换方式,会将【凡是遇到a就替换ok】,很明显,我们的需求不是这样的,我只希望单个的a替换掉,链接再一起的,我不想替换,于是乎,代码来了:
public string RewriteReplace(string baseStr = null, Dictionary<string, string> dic = null)
{
var list = CharacterReplace(baseStr);
var resData = list.Select(x => dic.ContainsKey(x) ? dic[x] : x).ToList();
return string.Join("", resData);
}
private List<string> CharacterReplace(string str)
{
List<string> list = new List<string>();
var sps = str.ToArray();
string baseData = string.Empty;
bool indexType = false;//当前字符是否为字母 (双面性)
bool? lastType = null;//上个字符是否是字母 (双面性)
for (var i = 0; i < sps.Length; i++)
{
var c = sps[i];
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
{
if (!indexType) // 从非字母转过来的
{
indexType = !indexType;
}
if (!lastType.HasValue)
{
lastType = indexType;
}
}
else
{
if (indexType) // 从字母转过来的
{
indexType = !indexType;
}
if (!lastType.HasValue)
{
lastType = indexType;
}
}
if (lastType != indexType && !string.IsNullOrEmpty(baseData))
{
var data = new string(baseData);
list.Add(data);
baseData = string.Empty;
lastType = indexType;
}
baseData = baseData + c.ToString();
if (i == (sps.Length - 1) && !string.IsNullOrEmpty(baseData))
{
list.Add(baseData);
}
}
return list;
}
然后我们调用这个替换的方法:
string oldStr = @"a+Abac+a1+a2+a+b+a+c*a+c,a,ba,u/a";
Dictionary<string, string> dic = new Dictionary<string, string>();
dic.Add("a", "ok");
string newStr = new Program().RewriteReplace(oldStr , dic);
于是乎,终于得到我们想要的数据【ok+Abac+ok1+ok2+ok+b+ok+c*ok+c,ok,ba,u/ok】。当然了,上面的方法对常见的字符替换是没有问题,但是灵活性太低,如果要替换所有的,我专门写了下面的方法:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace Sewerage.ApplicationCore.Util.StringOperation
{
public class StringReplace
{
public static string ReplaceString(string input, string OldStr, string NewStr)
{
string OlderString = input;
string[] Arr = new string[] { "+", "-", "*", "/", "(", ")", "{", "}", "[", "]", " " };
foreach (var item in Arr)
{
OlderString = OlderString.Replace(item, "#");
}
string[] strArr = OlderString.Split('#');
string str = "";
int Count = strArr.Where(s => s == OldStr).Count();
if (Count==0)
{
return input;
}
for (int i = 0; i < Count; i++)
{
if (i == 0)
{
str = Replce(input, OldStr, NewStr);
}
else
{
str = Replce(str, OldStr, NewStr);
}
}
return str;
}
public static string Replce(string input, string OldStr, string NewStr)
{
char[] charArr = input.ToCharArray();
int StartIndex = 0, EndIndex = 0;
Regex re = new Regex(@"[A-Za-z]|[0-9]");
int j = 0;
List<ReplaceData> ReplaceDataList = new List<ReplaceData>();
Regex rex = new Regex(@"^\d+$");
while (EndIndex < charArr.Length)
{
while (re.IsMatch(charArr[EndIndex].ToString()))
{
if (EndIndex >= charArr.Length - 1)
{
break;
}
else
{
EndIndex++;
}
}
if (StartIndex == 0 && re.IsMatch(charArr[0].ToString()))
{
ReplaceData replaceData = new ReplaceData();
replaceData.StartIndex = StartIndex;
replaceData.EndIndex = EndIndex - 1;
replaceData.Data = input.Substring(0, EndIndex);
ReplaceDataList.Add(replaceData);
StartIndex = EndIndex;
EndIndex++;
StartIndex++;
j++;
}
else if (StartIndex == 0 && !re.IsMatch(charArr[0].ToString()))
{
StartIndex = EndIndex;
EndIndex++;
StartIndex++;
}
else if (!re.IsMatch(charArr[StartIndex].ToString()))
{
EndIndex++;
StartIndex++;
}
else
{
ReplaceData replaceData = new ReplaceData();
replaceData.StartIndex = StartIndex;
if (EndIndex >= charArr.Length - 1 && re.IsMatch(charArr[EndIndex].ToString()))
{
replaceData.EndIndex = EndIndex;
replaceData.Data = input.Substring(StartIndex, EndIndex + 1 - StartIndex);
}
else
{
replaceData.EndIndex = EndIndex - 1;
replaceData.Data = input.Substring(StartIndex, EndIndex - StartIndex);
}
ReplaceDataList.Add(replaceData);
StartIndex = EndIndex;
EndIndex++;
StartIndex++;
j++;
}
}
int ObjectCount = ReplaceDataList.Where(s => s.Data == OldStr).Count();
if (ObjectCount != 0)
{
ReplaceData Replace = ReplaceDataList.Where(s => s.Data == OldStr).FirstOrDefault();
input = input.Substring(0, Replace.StartIndex) + NewStr + input.Substring(Replace.EndIndex + 1, input.Length - (Replace.EndIndex + 1));
}
return input;
}
private class ReplaceData
{
public int StartIndex { get; set; }
public int EndIndex { get; set; }
public string Data { get; set; }
}
}
}