String.Trim()可以删除正则表达式\ S匹配的字符吗?

时间:2013-09-05 19:56:46

标签: c# regex

如果可能,请帮助我理解:

var regexMatch = Regex.Match(inputString, "(\S*\d+\S*|\d)+");

if (regexMatch.Value == String.Empty)
{
    return null;
}
else
{
    var trimmedString = regexMatch.Value.Trim();

    if(trimmmedString != regexMatch.Value)
    {
        //Is there any value for inputString that makes this reachable?
    }
}

3 个答案:

答案 0 :(得分:7)

从.NET 4.0开始,Trim使用Char.IsWhiteSpace方法来决定修剪内容; documentation列出了要修剪的所有字符。由于\S的文档没有说它使用相同的字符列表,因此询问是否存在不匹配是一个公平的问题。

找出答案的一种方法是详尽的搜索:

var ws = new Regex("\\S");
for (char c = '\0'; c != 0xffff; c++) {
    if (char.IsWhiteSpace(c)) {
        var m = ws.Match("" + c);
        if (m.Value.Length != 0) {
            Console.Error.WriteLine("Found a mismatch: {0}", (int)c);
        }
    }
}

运行此代码不会产生任何结果:char.IsWhitespace认为空白与正则表达式的\S匹配的26个字符中没有一个。因此,我必须得出结论,trimmmedString != regexMatch.Value条件保护的代码无法访问。

作为旁注,regexMatch.Value永远不会是nullaccording to the documentation

  

如果对Regex.MatchMatch.NextMatch方法的调用未能找到匹配项,则返回的Match.Value属性的值为String.Empty

您可以删除第一个if,或将其替换为String.Empty

答案 1 :(得分:4)

您的代码有点疑问,但我会回答String.Trim()是否等同于使用\s删除前导和尾随空格的问题。

它们与.NET Framework 4.0相同

  • 从.NET 4.0开始,String.Trim()会移除前导和尾随字符,使Char.IsWhitespace()返回 true

    Char.IsWhitespace()categories Zl, Zp, Zs中的字符返回 true ,根据文档中的说明,以及\t\n,{{ 1}},\v\f\r

    请注意,似乎存在一些差异。根据{{​​3}},\x85属于U+00A0 NO-BREAK SPACE类别,但MSDN并未将其放在Zs文档中的空格分隔符列表中。测试显示Char.IsWhitespace()匹配\s,这意味着U+00A0U+00A0类别中的一个字符。

  • 根据页面fileformat.info\p{Z}相当于\s[\f\n\r\t\v\x85\p{Z}]类别目前包含3个子类别:Zs,Zl,Zp。

它们在.NET 4.0之前不等效

根据Z文件:

  

由于此更改,.NET Framework 3.5 SP1及更早版本中的Trim方法删除了.NET Framework 4及更高版本中的Trim方法的两个字符String.Trim()ZERO WIDTH SPACE (U+200B)不会删除。

     

此外,.NET Framework 3.5 SP1及更早版本中的Trim方法不会修剪三个Unicode空格字符:ZERO WIDTH NO-BREAK SPACE (U+FEFF)MONGOLIAN VOWEL SEPARATOR (U+180E)NARROW NO-BREAK SPACE (U+202F)

简而言之,MEDIUM MATHEMATICAL SPACE (U+205F)会考虑在4.0之前的.NET版本中删除不同的字符集

正则表达式中String.Trim()的规范与.NET 1.1保持一致。

答案 2 :(得分:3)

dasblinkenlight answer错误,行为从.NET 3.5更改为.NET 4.0。请参阅"Notes to Callers" here。稍微改变他的代码以便它实际使用Trim()测试找不到.NET 4.0的匹配但是找到了.NET 3.5的两个匹配

public class Program
{

    private static void Main(string[] args)
    {
        var ws = new Regex("\\S");
        for (char c = '\0'; c != 0xffff; c++)
        {
            if (new String(c, 1).Trim().Length == 0)
            {
                var m = ws.Match("" + c);
                if (m.Value.Length != 0)
                {
                    Console.Error.WriteLine("Found a mismatch: {0}", (int)c);
                }
            }
        }

        Console.WriteLine("done");
        Console.ReadLine();
    }

}

//Output running in .NET 3.5:
//Found a mismatch: 8203
//Found a mismatch: 65279
//done


//Output running in .NET 4.0:
//done