C# 正在寻找一个报价匹配注册表项
我想要的是C#的正则表达式,它将改变这一点:C# 正在寻找一个报价匹配注册表项,c#,regex,C#,Regex,我想要的是C#的正则表达式,它将改变这一点: "*one*" *two** two and a bit "three four" 为此: "*one*" "*two**" two and a bit "three four" 即带引号的字符串无论包含一个或多个单词都应保持不变 任何带星号的单词都要用双引号括起来 任何不带星号的未加引号的单词将保持不变 很高兴拥有: 如果多个星号可以合并成一个在同一个步骤,这将是更好的。 不属于引用字符串一部分的干扰词(如and、a、the)应被转储 谢谢你的
"*one*" *two** two and a bit "three four"
为此:
"*one*" "*two**" two and a bit "three four"
即带引号的字符串无论包含一个或多个单词都应保持不变
任何带星号的单词都要用双引号括起来
任何不带星号的未加引号的单词将保持不变
很高兴拥有:
如果多个星号可以合并成一个在同一个步骤,这将是更好的。
不属于引用字符串一部分的干扰词(如and、a、the)应被转储
谢谢你的帮助/建议
Julio以下正则表达式将满足您的需要:
\*+ # Match 1 or more *
(
\w+ # Capture character string
)
\*+ # Match 1 or more *
如果将此语句与此replace语句结合使用,则(\w+)匹配的所有单词将被包装在“**”
:
注意:这将使以下字符串不带引号:
*two two*
如果还希望匹配这些字符串,请使用以下正则表达式:
\*+([^*]+)\*+
编辑:更新的代码 此解决方案适用于您的请求,也适用于您想要的物品:
string text = @"test the ""one"" and a *two** two and a the bit ""three four"" a";
string result = Regex.Replace(text, @"\*+(.*?)\*+", @"""*$1*""");
string noiseWordsPattern = @"(?<!"") # match if double quote prefix is absent
\b # word boundary to prevent partial word matches
(and|a|the) # noise words
\b # word boundary
(?!"") # match if double quote suffix is absent
";
// to use the commented pattern use RegexOptions.IgnorePatternWhitespace
result = Regex.Replace(result, noiseWordsPattern, "", RegexOptions.IgnorePatternWhitespace);
// or use this one line version instead
// result = Regex.Replace(result, @"(?<!"")\b(and|a|the)\b(?!"")", "");
// remove extra spaces resulting from noise words replacement
result = Regex.Replace(result, @"\s+", " ");
Console.WriteLine("Original: {0}", text);
Console.WriteLine("Result: {0}", result);
第二个正则表达式替换噪声字可能会导致空格重复。为了弥补这个副作用,我添加了第三个regex替换项来清理它。类似这样的东西
ArgumentReplacer
是为每个匹配调用的回调。返回值被替换为返回的字符串
void Main() {
string text = "\"one\" *two** and a bit \"three *** four\"";
string finderRegex = @"
(""[^""]*"") # quoted
| ([^\s""*]*\*[^\s""]*) # with asteriks
| ([^\s""]+) # without asteriks
";
return Regex.Replace(text, finderRegex, ArgumentReplacer,
RegexOptions.IgnorePatternWhitespace);
}
public static String ArgumentReplacer(Match theMatch) {
// Don't touch quoted arguments, and arguments with no asteriks
if (theMatch.Groups[2].Value.Length == 0)
return theMatch.Value;
// Quote arguments with asteriks, and replace sequences of such
// by a single one.
return String.Format("\"%s\"",
Regex.Replace(theMatch.Value, @"\*\*+", "*"));
}
模式中左侧的备选方案优先于右侧的备选方案。这就是为什么我只需要在最后一个备选方案中编写“[^\s”“]+
”
另一方面,引号只有出现在参数开头时才匹配。如果它们出现在争论的中间,它们就不会被检测到,我们必须在它们发生之前停止。 如果你想匹配成对的引文,我认为你的语言不是很强>正则< /强>,因此我不认为正则表达式是一个好的解决方案。例如
请参见我决定遵循几个响应的建议,使用解析器解决方案。到目前为止,我已经尝试了一些正则表达式,但在某些情况下它们似乎失败了。这可能表明正则表达式不是这个问题的合适解决方案。感谢所有的回复。对于解析器来说,这可能是一个更好的工作。在已经被引用的字符串中可以有星号吗?如果是的话,结果应该是什么?如果星号在字符串的两端,例如“字符串”,那就好了。如果没有,它们无论如何都会被忽略。您需要使用惰性运算符,以便具有多个匹配项的字符串也能工作:1-2-3所以使用:*+([^*]+?)*+您是指这样的字符串:
*1**2*
?如果是这样,替换将正常工作。@Greg Miller-要么您的注释中的文本有问题,要么您没有发现“[^*]+”将匹配所有内容,但不包括没有惰性运算符的下一个星号。此模式将忽略简单的“**”;)
Original: test the "one" and a *two** two and a the bit "three four" a
Result: test "one" "*two*" two bit "three four"
void Main() {
string text = "\"one\" *two** and a bit \"three *** four\"";
string finderRegex = @"
(""[^""]*"") # quoted
| ([^\s""*]*\*[^\s""]*) # with asteriks
| ([^\s""]+) # without asteriks
";
return Regex.Replace(text, finderRegex, ArgumentReplacer,
RegexOptions.IgnorePatternWhitespace);
}
public static String ArgumentReplacer(Match theMatch) {
// Don't touch quoted arguments, and arguments with no asteriks
if (theMatch.Groups[2].Value.Length == 0)
return theMatch.Value;
// Quote arguments with asteriks, and replace sequences of such
// by a single one.
return String.Format("\"%s\"",
Regex.Replace(theMatch.Value, @"\*\*+", "*"));
}