Java 如何使用StringTokenizer从表达式中分离变量和数组?

Java 如何使用StringTokenizer从表达式中分离变量和数组?,java,Java,我试图将数组和变量从表达式中分离出来,这样就可以用数组名或变量填充两个ArrayLists。我正在使用StringTokenizer。我已经对表达式进行了分解,但是我很难确定哪些标记是数组名,哪些是变量 public void buildSymbols() { String s = expr; // input from different part of the program StringTokenizer st = new StringTokenizer(s, "+-*/

我试图将数组和变量从表达式中分离出来,这样就可以用数组名或变量填充两个
ArrayLists
。我正在使用
StringTokenizer
。我已经对表达式进行了分解,但是我很难确定哪些标记是数组名,哪些是变量

public void buildSymbols() {
    String s = expr; // input from different part of the program 
    StringTokenizer st = new StringTokenizer(s, "+-*/[]() ");
    while(st.hasMoreElements()){
        String temp = st.nextToken();
        System.out.println(temp);
    }
}
我打印temp只是为了确保表达式是分开的,但是给定一个表达式,例如
(varx+vary*varz[(vara+varb[(a+b)*33])/55
我不知道如何判断
varz
varb
是数组名,而varx、vary、vara、a和
b
是变量

你知道怎么做吗?

试试String.split()方法。它是字符串标记器的替代品。可以将字符串拆分为由分隔符拆分的较小字符串数组,就像StringTokenizer一样。但是,您可以分别执行两次,第一次使用括号,第二次使用其他符号。然后您就知道字符串数组的最后一个索引是数组的名称

String s = expr;
String[] brackSplit = s.split("\\[");
for (String str : brackSplit) {
    String[] finalSplit = str.split("*+-/()");
    //finalSplit[finalSplit.length - 1] = Array Name!
}
注意:StringTokenizer在新版本的Java中越来越不受欢迎。string split()方法已成为按分隔符拆分字符串的新“推荐”方法。

尝试string.split()方法。它是字符串标记器的替代品。可以将字符串拆分为由分隔符拆分的较小字符串数组,就像StringTokenizer一样。但是,您可以分别执行两次,第一次使用括号,第二次使用其他符号。然后您就知道字符串数组的最后一个索引是数组的名称

String s = expr;
String[] brackSplit = s.split("\\[");
for (String str : brackSplit) {
    String[] finalSplit = str.split("*+-/()");
    //finalSplit[finalSplit.length - 1] = Array Name!
}

注意:StringTokenizer在新版本的Java中越来越不受欢迎。string split()方法已成为通过分隔符拆分字符串的新的“推荐”方法。

我同意EJP:正确的解决方案是使用特定的解析器。但是,如果您愿意识别每次调用
StringTokenizer.nextToken
都找到了哪个定界器,您可以告诉StringTokenizer也返回定界器。此外,您还需要检索每个当前令牌上的下一个定界符(作为前瞻)。为此,最好将所有令牌存储在一个列表中:

public void buildSymbols() {
    String s = expr; // input from different part of the program 
    StringTokenizer st = new StringTokenizer(s, "+-*/[]() ", true);
    Set<String> delimiters=new HashSet<String>(Arrays.asList(new String[]{"+","-","*","/","[","]","(",")"," "}));
    List<Object> tokens=Collections.list(st);
    for(int i=0;i<tokens.size();i++){
        String temp = tokens.get(i).toString();
        if (delimiters.contains(temp))
        {
            // It is a delimiter
        }
        else
        {
            // It is a term
            boolean isAnArray=(isNextTokenAnOpenBracket(tokens, i));
            ...
        }
        System.out.println(temp);
    }
}

private boolean isNextTokenAnOpenBracket(List<Object> tokens, int currentIndex)
{
    return (currentIndex < tokens.size() && "[".equals(tokens.get(1 + currentIndex)));
}
public void buildSymbols(){
字符串s=expr;//来自程序不同部分的输入
StringTokenizer st=新的StringTokenizer,“+-*/[]()”,true);
Set delimiters=newhashset(Arrays.asList(新字符串[]{“+”、“-”、“*”、“/”、“[”、“]”、“(“,”)、“}”);
列表标记=Collections.List(st);

对于(int i=0;i我同意EJP:正确的解决方案是使用特定的解析器。但是,如果您愿意识别通过每次调用
StringTokenizer.nextToken
找到的定界符,您可以告诉StringTokenizer也返回定界符。此外,您还需要在每个当前令牌上检索下一个定界符(作为前瞻)。为此,最好将所有令牌存储在一个列表中:

public void buildSymbols() {
    String s = expr; // input from different part of the program 
    StringTokenizer st = new StringTokenizer(s, "+-*/[]() ", true);
    Set<String> delimiters=new HashSet<String>(Arrays.asList(new String[]{"+","-","*","/","[","]","(",")"," "}));
    List<Object> tokens=Collections.list(st);
    for(int i=0;i<tokens.size();i++){
        String temp = tokens.get(i).toString();
        if (delimiters.contains(temp))
        {
            // It is a delimiter
        }
        else
        {
            // It is a term
            boolean isAnArray=(isNextTokenAnOpenBracket(tokens, i));
            ...
        }
        System.out.println(temp);
    }
}

private boolean isNextTokenAnOpenBracket(List<Object> tokens, int currentIndex)
{
    return (currentIndex < tokens.size() && "[".equals(tokens.get(1 + currentIndex)));
}
public void buildSymbols(){
字符串s=expr;//来自程序不同部分的输入
StringTokenizer st=新的StringTokenizer,“+-*/[]()”,true);
Set delimiters=newhashset(Arrays.asList(新字符串[]{“+”、“-”、“*”、“/”、“[”、“]”、“(“,”)、“}”);
列表标记=Collections.List(st);

对于(int i=0;i您有办法,它们都被
[
字符取代;您可以(轻松地)检查左括号元素(
[
)及其前面的任何内容,它都是一个数组…直到它以
]
结束/结束(注意数组中的数组)这是我第一次使用StringTokenizer,有没有办法检查哪个分隔符在分隔标记,这样我就可以确定哪个标记在
[
?您无法从这里到达那里。
StringTokenizer
是解决此问题的错误工具。您需要为自己编写一个合适的词法分析器。您必须处理多字符标识符、多位数数字文本和几种类型的特殊字符,以及可能不同的长度。表达式不一定包含任何分隔符(例如空格)。你有办法,它们都会被
[
字符取代;你可以(轻松地)检查左括号元素(
[
),不管它前面是什么,它都是一个数组…直到它以
]
结束/结束(注意数组中的数组)这是我第一次使用StringTokenizer,有没有办法检查哪个分隔符在分隔标记,这样我就可以确定哪个标记在
[
?您无法从这里到达那里。
StringTokenizer
是解决此问题的错误工具。您需要为自己编写一个合适的词法分析器。您必须处理多字符标识符、多位数数字文本和几种类型的特殊字符,以及可能不同的长度。表达式不一定包含任何分隔符(例如空格)。
String[]brackSplit=s.split(“[”)
为索引0附近的
“未关闭的字符类”提供了一个
PatternSyntaxException
。很抱歉,我将其更改为“\[”。您需要转义字符才能正确解释它。
String[]brackSplit=s.split(“[”)
索引0附近的未关闭字符类提供了一个
模式SyntaxException
很抱歉。我将其更改为“\[”。您需要转义字符才能正确解释它。