2

a-zまたは*/+、などの文字の前にある数字を削除-し、その文字に続く別の文字の前にある数字を削除しようとしています。これが私が持っているものです。

    s= s.replaceAll("(\\d+)", "");
    s= s.replace("*", r.toString());

s読み取る必要がある文字列はどこにrあり、操作の結果です。

*任意です。任意の文字にすることができます。前述しました

これの問題は、文字列内のすべての数字が削除されることです。

次の入力で 1 回反復する場合:

    26 + 4 - 2

プログラムはこれを返します:

    30 - 

3 つの数字をすべて削除し、「+」を 30 に置き換えます。

これを次のように変更したいと思います(1回の繰り返しで):

    26 + 4 - 2

最初の正規表現は、最初の数値セットを削除します

    + 4 - 2

2番目は、演算子の後、次の演算子の前に数字を削除します

    + - 2

次のステートメントは、演算子を式の結果に置き換えます

    30 - 2

サイン、コサインなどの他の関数の問題についても同じことを望みます。

注: サインは「a」です

「シンピ」は「アピ」と同じです。

1回の繰り返しの後、次のようになります

    a pi + 2

    a + 2

    0 + 2

コードのサンプルを次に示します。

これがMultiplyの「ケース」です

    case '*':
                    {
                        int m = n + 1;
                        while (m < result.length){
                            if (result[m] != '*' && result[m] != '/' && result[m] != '+' && result[m] != '-'){ //checks the item to see if it is numeric
                                char ch2 = result[m]; //makes the number a character
                                number3 += new String(new char[]{ch2}); //combines the character into a string. For example: '2' + '3' = "23".
                                ++m;}
                            else {
                                    break;
                                }}
                        resultNumber = (Double.parseDouble(number2) * Double.parseDouble(number3)); //"number2" holds the value of the numbers before the operator. Example: This number ----> "3" '*' "23"
                        equation = equation.replaceAll("(\\d+)", "");  //  <---- Line I pulled out earlier that I want to change.
                        equation = equation.replace("*", resultNumber.toString()); // <----- Line I pulled out earlier
                        result = equation.toCharArray();
                        number3 = ""; //erases any number held
                        number2 = ""; //erases any number held
                        ++n;
                        break;
                    }
4

1 に答える 1

0

最初に 2 つの代替アプローチを提案し、それから現状の質問に答えます。

おそらく正規表現なしの方が良いでしょう

あなたの申請について多くの疑問があります。適切なトークナイザー (レクサー)と非常に単純なパーサーを組み合わせた方が、コードよりも優れた仕事をし、より明確なエラー メッセージを表示する可能性があります。

すべてのオペランドの一致

正規表現を使用する場合でも、1 回のパスで両方のオペランドを一致させる方が理にかなっている場合があります。つまり(\d+)\s*\*\s*(\d+) 、正確に 2 つの数値の乗算に一致します。最初に一致を検索し、次にキャプチャ グループからオペランドを抽出し、結果の値を計算して、最後に結果を含む部分文字列を結合することができます。

// Multiplication of unparenthesized integers
Pattern p = Pattern.compile("(\\d+)\\s*\\*\\s*(\\d+)");
Matcher m = p.matcher(s);
while (m.find()) {
  int a = Integer.parseInt(m.group(1));
  int b = Integer.parseInt(m.group(2));
  s = s.substring(0, m.start(1)) + (a*b) + s.substring(m.end(2));
  m.reset(s);
}

タイトルに書かれていた質問への回答

あなたの質問の正確な定式化について:

文字値の前で正規表現を停止し、その文字の後に別の正規表現を開始する方法はありますか?

入力内の特定の文字の後に正規表現が一致しないようにする場合は、否定の後読みアサーションによって実現できます。同様に、特定の文字の後にのみ一致させるには、肯定的な後読みアサーションを使用できます。

したがって、 で始まる正規表現(?<!\*.*)は の最初の出現までしか一致しませんが'*'、 で始まる正規表現(?<=\*.*)はその文字の最初の出現の後にのみ一致します。どちらも を使用してコンパイルするDOTALLか、 のようなより複雑な形式でコンパイルする必要があり(?<!\*(?:\n|.*)*)ます。

しかし、これらの一致があなたが考えている数学に対応していることを確認することは、おそらく非常に難しいでしょう.

于 2013-04-24T08:06:26.270 に答える