0

我使用 Java Pattern 类将正则表达式指定为字符串。

例如,我喜欢成为蜘蛛侠:“彼得帕克”

应该将蜘蛛侠和“彼得帕克”列为单独的标记。谢谢

try {
     BufferedReader br = new BufferedReader(new FileReader(f));
     StringBuilder sb = new StringBuilder();
     String line = br.readLine();

     while (line != null) {
        sb.append(line);
        line = br.readLine();
     }

    String everything = sb.toString();        
    List<String> result = new ArrayList<String>();
    Pattern pat = Pattern.compile("([\"'].*?[\"']|[^ ]+)");
    PatternTokenizer pt = new PatternTokenizer(new StringReader(everything),pat,0);
    while (pt.incrementToken()) {
     result.add(pt.getAttribute(CharTermAttribute.class).toString());

     }

 }
    catch (Exception e) {
    throw new RuntimeException(e);
   }

所以我猜“某个词”不起作用的原因是因为每个标记本身就是一个字符串。有什么提示吗?谢谢

4

2 回答 2

2

如果它不必是正则表达式并且您在 String 中的数据是正确的(引号的顺序不正确" ' some data " '),那么您可以在一次迭代中完成它

String data="I love being spider-man : \"Peter Parker\" or 'photo reporter'";

List<String> tokens = new ArrayList<String>();
StringBuilder sb=new StringBuilder();
boolean inSingleQuote=false;
boolean indDoubleQuote=false;

for (char c:data.toCharArray()){
    if (c=='\'') inSingleQuote=!inSingleQuote;
    if (c=='"') indDoubleQuote=!indDoubleQuote;
    if (c==' ' && !inSingleQuote && !indDoubleQuote){
        tokens.add(sb.toString());
        sb.delete(0,sb.length());
    }
    else 
        sb.append(c);
}
tokens.add(sb.toString());
System.out.println(tokens);

输出

[I, love, being, spider-man, :, "Peter Parker", or, 'photo reporter']
于 2012-07-12T00:43:31.817 回答
1

检查此正则表达式是否是您需要的:

"([\"'].*?[\"']|(?<=[ :]|^)[a-zA-Z0-9-]+(?=[ :]|$))"

我假设您在(单/双)引号内没有(单/双)引号。

还有关于分隔符的假设:我只允许空间并:作为分隔符工作。什么都不会匹​​配"foo_bar"。如果要添加更多分隔符,例如;, ., ,, ?,请将其添加到前瞻和后视断言中的字符类中,如下所示:

"([\"'].*?[\"']|(?<=[ :;.,?]|^)[a-zA-Z0-9-]+(?=[ :;.,?]|$))"

尚未对每个输入进行测试,但我已经对此输入进行了测试:

"    sdfsdf \" sdfs  sdfsdfs \"   \"sdfsdf\"  sdfsdf   sdfsd  dsfshj sdfsdf-sdf  'sdfsdfsdf  sd f '  "
// I used replaceAll to check the captured group
.replaceAll("([\"'].*?[\"']|(?<=[ :]|^)[a-zA-Z0-9-]+(?=[ :]|$))", "X$1Y")

它对我来说很好。

如果您想要更自由的捕获,但仍然假设引用:

"([\"'].*?[\"']|[^ ]+)"

要提取匹配项:

Matcher m = Pattern.compile(regex).matcher(inputString);
List<String> tokens = new ArrayList<String>();
while (m.find()) {
    tokens.add(m.group(1));
}
于 2012-07-12T00:32:26.500 回答