0

かなり奇妙な動作をしている正規表現があり、その理由がわかりません。元の正規表現:

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 メソッドは、コードの他の部分で問題なく何度も呼び出されます。つまずきのブロックにぶつかったのは、この 1 つの Regex だけです。

4

2 に答える 2

2

表示されている動作は、アプリケーションロジックとは完全に関係しており、正規表現とはほとんど関係がありません。でGetMatchIndex、デフォルトになっていindex = 0ます。string[] inputでは、一致するエントリがない場合はどうなりますか?の最初の要素であるindex = 0のインデックスである、が返されます。DDR3string[] input

に一致するため、最初の正規表現にはその動作は表示されません1.35v。ただし、最後にスペースを追加すると、分割入力のどのエントリとも一致しないため、デフォルトでは最初のエントリが返されます。これはたまたまですDDR3。また、if (rgx1Match.Success)最初に文字列全体で一致するものをチェックし(スペースがあるため一致する)、分割後にインデックスを検索してスペースを削除するため、実際には役に立ちません。

修正は非常に簡単です。0ベースの番号付けを使用するプログラミング言語で配列からインデックスを返す場合、「見つからない」を表す標準的な方法は-1を使用するため、有効な結果と混同されません。の0。したがって、デフォルトindex-1代わりに、の結果を-1特殊なケースとして処理します。つまり、「一致なし」などのエラーメッセージをユーザーに表示します。

于 2013-03-07T21:44:46.360 に答える
1

あなたの質問は間違っています:

new Regex(@"(?i)\d\.\d\dv\s").Match("DDR3").Success 偽です

実際、結果は希望どおりに動作するようです。

于 2013-03-07T21:14:49.437 に答える