正则表达式,用于保留引号,单引号,连字符和空格分割

时间:2012-07-12 00:16:26

标签: java regex

我使用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);
   }

所以我猜“某些单词”不起作用的原因是因为每个标记本身就是一个字符串。 任何线索?谢谢

2 个答案:

答案 0 :(得分:2)

如果它不必是正则表达式并且您的String中的数据是正确的(引号的顺序不正确" ' some data " ')那么您可以在一次迭代中执行此操作< / p>

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']

答案 1 :(得分: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));
}