寻找与Regex匹配的报价

时间:2009-09-04 16:42:12

标签: c# regex

我正在使用C#的正则表达式来解决这个问题:

"*one*" *two** two and a bit "three four"

进入这个:

"*one*" "*two**" two and a bit "three four"

IE引用的字符串应该保持不变,无论它是否包含一个或多个单词。

任何带有星号的单词都用双引号括起来。

任何没有星号的未加引号的词语都不会改变。

很高兴: 如果可以在同一步骤中将多个星号合并为一个更好的星号。 应该转储噪音词 - 例如和,a, - 不是引用字符串的一部分。

感谢您提供任何帮助/建议。

5 个答案:

答案 0 :(得分:1)

以下正则表达式可以满足您的需求:

\*+            # Match 1 or more *
 (
  \w+          # Capture character string
 )
\*+            # Match 1 or more *

如果你将这个与此替换语句结合使用,那么与(\ w +)匹配的所有单词都将包含在"**"中:

string s = "\"one\" *two** two and a bit \"three four\"";
Regex r = new Regex(@"\*+(\w+)\*+");

var output = r.Replace(s, @"""*$1*""");

注意:这会使下面的字符串不加引号:

*two two*

如果您希望匹配这些字符串,请使用此正则表达式:

\*+([^*]+)\*+

答案 1 :(得分:1)

编辑:更新了代码。

此解决方案适用于您的请求,以及有物品的好处:

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);

<强>输出:

Original: test the "one" and a *two** two and a the bit "three four" a
Result: test "one" "*two*" two bit "three four" 

第二个正则表达式替换噪音词会导致空格的重复。为了弥补这种副作用,我添加了第三个正则表达式替换来清理它。

答案 2 :(得分:0)

像这样的东西。 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""]+”。

另一方面,引号只有在参数开头出现时才匹配。如果它们出现在论证的中间,则不会被检测到,如果它们发生,我们必须在它们之前停止。

答案 3 :(得分:0)

鉴于您希望匹配引号对,我认为您的语言不是常规,因此我认为RegEx不是一个好的解决方案。 E.g

  

Some people, when confronted with a problem, think “I know, I'll use   regular expressions.”
Now they have two problems.

请参阅"When not to use Regex in C# (or Java, C++ etc)"

答案 4 :(得分:0)

我决定遵循一些回复的建议并使用解析器解决方案。我已经尝试了迄今为止所贡献的正则表达式,并且在某些情况下它们似乎失败了。这可能表明正则表达式不是解决此问题的适当方法。感谢所有回复。