1

我正在使用 C# 在 Visual Studios 2013 Express 中编写正则表达式。我试图在每个包含单词和 !@#$%^&*()_- 的字符串周围加上单引号,除了:

  • 或者
  • 不是
  • 空的()
  • 不是空的()
  • 当前的日期()
  • 任何已经有单引号的字符串。

这是我的正则表达式和它的作用示例: https ://regex101.com/r/nI1qP0/1

我只想在捕获组周围加上单引号,而不触及非捕获组。我知道这可以通过环视来完成,但我不知道如何。

4

3 回答 3

1

您需要使用匹配评估器或回调方法。关键是您可以在此方法中检查匹配和捕获的组,并根据您的模式决定要采取的操作。

所以,添加这个回调方法(如果调用方法是非静态的,可能是非静态的):

public static string repl(Match m)
{
    return !string.IsNullOrEmpty(m.Groups[1].Value) ?
        m.Value.Replace(m.Groups[1].Value, string.Format("'{0}'", m.Groups[1].Value)) :
        m.Value;
}

然后,使用匹配评估器(=回调方法)的重载Regex.Replace

var s = "'This is not captured' but this is and not or empty() notempty() currentdate() capture";
var rx = new Regex(@"(?:'[^']*'|(?:\b(?:(?:not)?empty|currentdate)\(\)|and|or|not))|([!@#$%^&*_.\w-]+)");
Console.WriteLine(rx.Replace(s, repl));

请注意,您可以使用 lambda 表达式缩短代码:

Console.WriteLine(rx.Replace(s, m => !string.IsNullOrEmpty(m.Groups[1].Value) ?
    m.Value.Replace(m.Groups[1].Value, string.Format("'{0}'", m.Groups[1].Value)) :
    m.Value));

IDEONE 演示

于 2015-07-21T20:32:01.990 回答
1

我没有尝试忽略带有单词 and!@#$%^&*()_- 的字符串,而是将它们包含在我的搜索中,在任一端放置一个额外的单引号,然后删除两个单引号的所有实例像这样的引用:

 // Find any string of words and !@#$%^&*()_- in and out of quotes.
 Regex getwords = new Regex(@"(^(?!and\b)(?!or\b)(?!not\b)(?!empty\b)(?!notempty\b)(?!currentdate\b)([\w!@#$%^&*())_-]+)|((?!and\b)(?!or\b)(?!not\b)(?!empty\b)(?!notempty\b)(?!currentdate\b)(?<=\W)([\w!@#$%^&*()_-]+)|('[\w\s!@#$%^&*()_-]+')))", RegexOptions.IgnoreCase);
 // Find all cases of two single quotes
 Regex getQuotes = new Regex(@"('')");

 // Get string from user
 Console.WriteLine("Type in a string");
 string search = Console.ReadLine();

 // Execute Expressions.
 search = getwords.Replace(search, "'$1'");
 search = getQuotes.Replace(search, "'");
于 2015-07-21T20:40:56.620 回答
1

您可以使用此正则表达式:

(?:'[^']*'|(?:\b(?:(?:not)?empty|currentdate)\(\)|and|or|not))|([!@#$%^&*_.\w-]‌​+)

此处忽略的匹配不会被捕获,并且可以使用 检索要引用的单词Match.Groups[1]。然后,您可以添加引号Match.Groups[1]并根据需要替换整个输入。

正则表达式演示

于 2015-07-21T18:17:10.623 回答