c#中不寻常的正则表达式行为

时间:2013-03-07 20:50:06

标签: c# regex

我有一个表现相当奇怪的正则表达式,我无法理解为什么。原始正则表达式:

Regex regex = new Regex(@"(?i)\d\.\d\dv");

此表达式返回/匹配等效于1.35V或1.35v,这是我想要的。但是,它对我的​​程序来说并不是唯一的,它会返回一些我不需要的字符串。

修改正则表达式:

Regex rgx = new Regex(@"(?i)\d\.\d\dv\s");

只需在表达式中添加'\ s',它就匹配/返回DDR3,这根本不是我想要的。我猜测正在发生某种反转,但我不明白为什么,我似乎无法找到解释它的参考。我想做的就是在表达式的末尾添加一个空格来过滤更多的结果。

非常感谢任何帮助。

编辑: 这是一个功能测试用例,其中包含我的代码中发生的一般版本。只需在Visual Studio中打开一个新的WPF,进行复制和粘贴,它就应该为您重复结果。

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
    {
        InitializeComponent();
    }
    Regex rgx1 = new Regex(@"(?i)\d\.\d\dv");
    Regex rgx2 = new Regex(@"(?i)\d\.\d\dv\s");

    string testCase = @"DDR3 Vdd            |            |            |            |            |    1.35v   |";

    string str = null;

    public void IsMatch(string input)
    {
        Match rgx1Match = rgx1.Match(input);
        if (rgx1Match.Success)
        {
            GetInfo(input);
        }
    }
    public void GetInfo(string input)
    {
        Match rgx1Match = rgx1.Match(input);
        Match rgx2Match = rgx2.Match(input);

        string[] tempArray = input.Split();
        int index = 0;

        if (rgx1Match.Success)
        {
            index = GetMatchIndex(rgx1, tempArray);
            str = tempArray[index].Trim();
            global::System.Windows.Forms.MessageBox.Show("First expression match: " + str);
        }
        if (rgx2Match.Success)
        {
            index = GetMatchIndex(rgx2, tempArray);
            str = tempArray[index].Trim();
            System.Windows.Forms.MessageBox.Show(input);
            global::System.Windows.Forms.MessageBox.Show("Second expression match: " + str);
        }
    }
    public int GetMatchIndex(Regex expression, string[] input)
    {
        int index = 0;

        for (int i = 0; i < input.Length; i++)
        {
            if (index < 1)
            {
                Match rgxMatch = expression.Match(input[i]);
                if (rgxMatch.Success)
                {
                    index = i;
                }
            }
        }
        return index;
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        string line;
        IsMatch(testCase);
    }

}

}

GetMatchesIndex方法在代码的其他部分被多次调用而没有发生意外,只是在这一个正则表达式上我遇到了绊脚石。

2 个答案:

答案 0 :(得分:2)

您看到的行为与您的应用程序逻辑完全相关,而与正则表达式几乎没有关系。在GetMatchIndex中,您违约index = 0。那么,如果string[] input中的所有条目都不匹配,会发生什么?您将返回index = 0DDR3的索引,string[] input中的第一个元素。

您在第一个正则表达式中没有看到该行为,因为它与1.35v匹配。但是,当您向末尾添加空格时,它与分割输入中的任何条目都不匹配,因此您默认返回第一个,恰好是DDR3。此外,if (rgx1Match.Success)并没有真正帮助,因为你首先检查整个字符串中的匹配(因为那里有空格,所以匹配),然后在拆分后搜索索引,这会删除空格! / p>

修复非常简单:当您使用基于0的编号的编程语言从数组返回索引时,表示“未找到”的标准方法是-1,因此不会混淆0的有效结果。因此,默认index改为-1,并将-1的结果作为一种特殊情况处理,即向用户显示错误消息,如“不匹配”。

答案 1 :(得分:1)

您的问题不正确:

new Regex(@"(?i)\d\.\d\dv\s").Match("DDR3").Success 是假的

事实上,结果似乎完全按照您的意愿运作。