3

次のような式を表す文字列入力があります。

BMI = ( Weight / ( Height  * Height ) ) * 703

すべての正当な変数を抽出できるようにしたいString[]

有効な変数は、英数字のみが許可されることを除いて、Java 変数の命名規則とほぼ同じ規則で決定されます。

  • 大文字または小文字の任意のアルファベット文字の後に数字が続く場合があります
  • 任意の単語/テキスト
  • 任意の単語/テキストの後に数字が続く

したがって、出力は次のようになると思います。

BMI
Weight
Height

これは私の現在の試みです:

/* helper method , find all variables in expression,
 * Variables are defined a alphabetical characters a to z, or any word , variables cannot have numbers at the beginning
 * using regex pattern "[A-Za-z0-9\\s]"
 */
public static List<String> variablesArray (String expression)
{
    List<String> varList = null; 
    StringBuilder sb = null; 
    if (expression!=null)
    {
        sb = new StringBuilder(); 

        //list that will contain encountered words,numbers, and white space
        varList = new ArrayList<String>();

        Pattern p = Pattern.compile("[A-Za-z0-9\\s]");
        Matcher m = p.matcher(expression);

        //while matches are found 
        while (m.find())
        {
            //add words/variables found in the expression 
            sb.append(m.group());
        }//end while 

        //split the expression based on white space 
        String [] splitExpression = sb.toString().split("\\s");
        for (int i=0; i<splitExpression.length; i++)
        {
            varList.add(splitExpression[i]);
        }
    }
    return varList; 
}

結果は私が期待したものではありません。余分な空行を取得し、「高さ」を 2 回取得しましたが、数値を取得するべきではありませんでした:

BMI


Weight


Height


Height



703
4

3 に答える 3

4

文字列を作成し、それを分割して配列に変換する理由がわかりません。その非効率性に加えて、すべての ID の後にスペースが続かない限り、この方法は機能しません。

出力で繰り返しを許可する、より単純なコードを次に示します。繰り返しを取り除くには、ListandArrayListSetandに置き換えHashSetます。

public class Test {

    public static List<String> variablesArray(String expression) {
        if (expression != null) {
            ArrayList<String> vars = new ArrayList<String>();
            Pattern p = Pattern.compile("[a-z][a-z0-9]*", Pattern.CASE_INSENSITIVE);
            Matcher m = p.matcher(expression);
            while (m.find()) {
                vars.add(m.group());
            }
            return vars;
        }
        return null;
    }

    public static void main(String[] args) {
        List<String> vars = variablesArray("BMI=(Weight/(Height*Height)) * 70");
        for (String var : vars) {
            System.out.println(var);
        }
    }
}

String []ではなくa を戻り値として実際に使用したい場合は、返さArrayList<String>れるときに変換を行います。

return vars.toArray(new String [vars.size()]);

最後に、あなたは何を達成しようとしているのだろうか。式に識別子のリストを含めることはあまり役に立ちません。たとえば、式を評価しようとしている場合、この ID のリストは必要なものではありません。

于 2012-06-26T02:13:00.833 に答える
0

使用:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Main
{
  public static void main (String[] args) throws java.lang.Exception
  {
     String formula = "BMI = ( Weight / ( Height * Height ) ) * 703";
     String pattern = "(?:^|(?<=[=+\\-*/()]))\\s*([a-z]+)\\s*(?:$|(?=[=+\\-*/()]))";
     Pattern p = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
     Matcher m = p.matcher(formula);
     while(m.find()) {
       System.out.println(m.group(1));
     }
  }
}

あなたが得るでしょう:

BMI
Weight
Height
Height

後は重複を削除するだけです。これは簡単な作業です。


こちらのコードを参照してテストしてください。

于 2012-06-26T00:22:03.170 に答える
0

この単純な正規表現は、すべての変数に一致するはずです。

"[A-Za-z_][A-Za-z0-9_]*"

自由に_名前に含めましたが、本当にしたくない場合は削除できます。

"[A-Za-z][A-Za-z0-9]*"

変数を一意に一致させることはできませんが、一致を挿入しSetて重複したエントリを削除することはできます。

于 2012-06-26T00:56:34.913 に答える