我需要转义用户输入的字符串中的 %
个字符 - 用 [%]
替换它们 除非它们在开头或字符串的结尾。
例如 %foo%foo[%]foo%
应该变成 %foo[%]foo[%]foo%
。空格不是问题:这都是关于转义任何字符串中间的百分号。
[^[]%[^\]]
的正则表达式将匹配中间字符串百分比,但也匹配相邻字符(因此 o%f
我的例子)。
是否有一个合理的正则表达式可以只匹配字符串中间的非转义百分号字符?
我想知道非正则表达式的解决方案是否更可取,例如
遍历字符串中的字符,并用转义的百分比构建替换字符串
const string TEST = "%foo%foo[%]foo%";
StringBuilder escaped = new StringBuilder();
escaped.Append(TEST[0]);
for (int i = 1; i < TEST.Length - 1; i++)
{
if (TEST[i] != '%' || (TEST[i - 1] == '[' && TEST[i] == '%' && TEST[i + 1] == ']'))
{
escaped.Append(TEST[i]);
}
else
{
escaped.Append("[%]");
}
}
escaped.Append(TEST[TEST.Length - 1]);
-或-
进行基于 token 的三遍替换,例如
const string TOKEN = "!PERCENT!"; // a string which we hope(!) we will never encounter in the string we're escaping
const string TEST = "%foo%foo[%]foo%";
string escaped = TEST.Replace("[%]", TOKEN);
escaped = replaced.Replace("%", TOKEN);
escaped = replaced.Replace(TOKEN, "[%]");
(尽管这也会转义任何第一个或最后一个字符百分比,这不是我想要的)
至于为什么我需要这样做 - 我正在转义 Like
过滤器表达式值,这些值由用户输入并应用于 DataTable
。
最佳答案
你可以试试:
(?<!^)((?<!\[)|(?!.\]))%(?!$)
它有点难看,因为我希望它匹配 foo[%foo 和 foo%]foo 的情况。
(?<!^) - Prevents match at start of string (negative look behind)
(?!$) - Prevents match at end of a string (negative look ahead)
(?<!\[)|(?!.\]) - Prevents a match if previous is '[' AND ']' is next.
您可以将其与正则表达式命令一起使用,例如:
Regex.Replace(input, @"(?<!^)((?<!\[)|(?!.\]))%(?!$)", x => "[" + x + "]")
https://stackoverflow.com/questions/5967542/