从字符串中提取字符和单词

时间:2016-02-23 03:40:03

标签: java

我想逐个字符地扫描输入行,并根据“true”, “false”, “^” “&”, “!”, “(”, “)”

的有效标记生成字符串

例如,如果给我一个字符串,例如String line = true & ! (false ^ true)

我必须生成令牌"true", "&", "!", "(", "false", "^", "true", ")"

我一直在尝试使用split()将字符串分成标记并将它们存储在像String[] result = line.split(" ")这样的数组中,然后在循环中使用一堆if语句来查看标记在该索引处匹配任何有效令牌并仅返回令牌。这是我到目前为止尝试使用的那种

for(int i = 0; i < line.length();i++){
    if(result[i].equals("true") || result[i].equals("false") || result[i].equals("^") 
        || result[i].equals("&") || result[i].equals("!") || result[i].equals("(")
        || result[i].equals(")")){
        nextToken = result[i];
}

但显然这不会提取彼此相邻的有效令牌,例如当字符串包含类似(true或此true^false的内容时,应返回三个令牌"true", "^", "false" 。有没有办法将不包含空格或任何特殊字符的字符串分成我感兴趣的标记?

5 个答案:

答案 0 :(得分:1)

只要输入准确,以下内容就会标记您的输入:

public class Tokenizer {

    public static void main(String[] args) {

        // true, false, ^ &, !, (, )
        String SYMBOLS = "^&!()";

        String line = "true&!(false^true)";
        List<String> tokens = new ArrayList<String>();

        char[] in = line.toCharArray();
        for (int i = 0; i<in.length; i++) {
            if (in[i] == ' ')
                continue;
            if (SYMBOLS.indexOf(in[i]) >= 0) {
                tokens.add(String.valueOf(in[i]));
            } else if (in[i] == 't') {
                tokens.add("true");
                i += "true".length()-1;
            } else if (in[i] == 'f') {
                tokens.add("false");
                i += "false".length()-1;
            }
        }

        for (String token : tokens)
            System.out.println(token);

    }
}

制作输出:

true
&
!
(
false
^
true
)

答案 1 :(得分:0)

尝试使用分隔符。它们将根据您设置为令牌的内容分隔字符串。我将查看此问题以获取更多信息:How do I use a delimiter in Java Scanner?

答案 2 :(得分:0)

编辑: -

如果你需要确切的顺序,你可以这样做: -

public static void main(String[] args)
{
    final String TOKENS = "true,false,!,),(";
    String [] splittedTokens = TOKENS.split(",");
    String Data = "'true','^','false'";

    ArrayList <String> existingTokens = new ArrayList<String>();
    for(int i = 0; i < splittedTokens.length; i++)
    {
        if(Data.contains(splittedTokens[i]))
        {
            existingTokens.add(splittedTokens[i]);
        }
    }

    for(int i = 0; i < splittedTokens.length; i++)
    {
        int count = 0;
        for(int j = 0; j < existingTokens.size(); j++)
        {
            if(splittedTokens[i].equals(existingTokens.get(j)))
            {
                count++;
            }
        }
        System.out.println("Number of "+splittedTokens[i]+" = "+count);
    }
}

如果您只需要该字符串包含的所有标记: -

public static void main(String[] args)
{
    final String TOKENS = "true,false,!,),(";
    String [] splittedTokens = TOKENS.split(",");
    String Data = "true^false";

    for(int i = 0; i < splittedTokens.length; i++)
    {
        if(Data.contains(splittedTokens[i]))
        {
            System.out.println("The String Contains "+ splittedTokens[i]);
        }
    }
}

答案 3 :(得分:0)

试试这个。

    String s = "String line=true&!(false^true)";
    String[] p = s.split("\\s+|(?<=[!()^&=])|\\b");
    System.out.print(Arrays.toString(p));
    // -> [String, , line, =, true, &, !, (, false, ^, true, )]

String s = "String line=true&!(false^true)";
Matcher m = Pattern.compile("\\w+|[()^&|!]").matcher(s);
while (m.find())
    System.out.println(m.group());

输出

String
line
true
&
!
(
false
^
true
)

答案 4 :(得分:0)

我使用正则表达式进行分段。您可以将其设置为返回仅有效值“true”,“false”,“^”,“&amp;”,“!”,“(”或“)”或有效列表的字符串列表同时生成任何无效分组(如果您想反映错误并指出错误)。

在匹配器循环中,只需使用返回的字符串值执行所需操作即可。查看此代码(注意,我只是输出用大括号括起来的值,而不是添加到数组中;你可以用它们做你想做的事。):

import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class QuickTest {
  public static void main(String[] args) {
    String testIn = "(true^false)&aaa!asa (bbb& ccc)";
    Pattern p1 = Pattern.compile("(true|false|\\^|\\&|\\!|\\(|\\))", Pattern.CASE_INSENSITIVE);
    Matcher m1 = p1.matcher(testIn);
    System.out.println("Match and return only the valid values");
    while (m1.find()) {
      if (m1.group().trim().length() > 0) {
        System.out.println("Found {" + m1.group() + "}");
      }
    }
    Pattern p2 = Pattern.compile("((true|false|\\^|\\&|\\!|\\(|\\))|([^\\^|\\&|\\!|\\(|\\)|\\s*]*)?)", Pattern.CASE_INSENSITIVE);
    Matcher m2 = p2.matcher(testIn);
    System.out.println("Match and return valid and invalid values");
    while (m2.find()) {
      if (m2.group().trim().length() > 0) {
        System.out.println("Found {" + m2.group() + "}");
      }
    }
  }
}

运行此命令,您将获得以下输出:

Match and return only the valid values
Found {(}
Found {true}
Found {^}
Found {false}
Found {)}
Found {&}
Found {!}
Found {(}
Found {&}
Found {)}
Match and return valid and invalid values
Found {(}
Found {true}
Found {^}
Found {false}
Found {)}
Found {&}
Found {aaa}
Found {!}
Found {asa}
Found {(}
Found {bbb}
Found {&}
Found {ccc}
Found {)}

这样做的另一个好处是,您可以从外部存储的有效值列表中实际构建正则表达式,从而使其更具动态性。