I have a string input that represents a formula like:
BMI = ( Weight / ( Height * Height ) ) * 703
I want to be able to extract all legal variables into a String[]
Legal variables are determined with almost the same rules as Java variable naming convention, except only alphanumeric characters are allowed:
Therefore I expect the output to look like this:
BMI
Weight
Height
This is my current attempt:
/* 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;
}
The result is not as I expected. I got extra empty lines, got "Height" twice, and shouldn't have gotten a number:
BMI
Weight
Height
Height
703
I'm not sure why you would make a string and split it to convert to an array. In addition to its inefficiency, the method won't work unless every ID occurrence is followed by space.
Here's a more straightforward code that allows repeats in the output. To get rid of repeats, just replace List and ArrayList with Set and 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);
}
}
}
If you actually want a String [] as the return value rather than the ArrayList<String>, then do the conversion as you're returning.
return vars.toArray(new String [vars.size()]);
Finally, I wonder what you are trying to accomplish. Having a list of identifiers in an expression doesn't seem very useful. If, for example, you are trying to evaluate the expression, this list of ids is not going to be what you need.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With