正则表达式用于将字符串分割成3个部分

3

我有一个类似以下所示的动态输入信息的例子:

Xbox 360(黑色)Elite主机120GB(伊利诺伊州梅森市)$200

$200 2013北道Camper(RT 202. 缅因州曼彻斯特)$224/月。

雪地摩托车自行车挂车(温斯罗普/奥古斯塔)$40每月

"Great Xmas Gift" XBox 360吉他英雄(斯普林菲尔德)

我正在尝试在Android中使用正则表达式将字符串分割成三部分:

  1. XXX()之前的文本
  2. (XXX)内的文本
  3. () XXX之后的文本

有时候价格会不存在,即()后面的文本。

我尝试过

Pattern p = Pattern.compile("\(([^]*)\)");
Matcher m = p.matcher(title);

但是我无法让 Android 中的匹配器工作。每当我用 matcher.group(1) 查看时,它总是返回空值。我目前设置为查找 ( 或 $,并分割字符串。但这样不准确且低效。

非常感谢任何帮助!


1
我猜你想包括 (Mason City Illinois) 但排除 (black) 是吗? - Peter Lawrey
是的,没错,这正是我遇到的问题之一。 - Nick
我猜你只想解析最后一个 () - Peter Lawrey
4个回答

4
我猜你可以用正则表达式实现这个功能,但不使用正则表达式可能更简单。
    String input[] = {
            "Xbox 360 (black) Elite Console 120GB (Mason City Illinois ) $200",
            "$200 2013 North Trail Camper (RT 202. Manchester, Maine) $224/mo.",
            "Snowmobile Bike trailers (Winthrop / Augusta) $40 Monthly",
            "\"Great Xmas Gift\" XBox 360 Guitar Hero (Springfied)"
    };
    for (String s : input) {
        int lastClose = s.lastIndexOf(')');
        int lastOpen = s.lastIndexOf('(', lastClose);
        System.out.println(s.substring(0, lastOpen).trim() +
                "~" + s.substring(lastOpen + 1, lastClose).trim() +
                "~" + s.substring(lastClose + 1).trim());
    }

打印输出
Xbox 360 (black) Elite Console 120GB~Mason City Illinois~$200
$200 2013 North Trail Camper~RT 202. Manchester, Maine~$224/mo.
Snowmobile Bike trailers~Winthrop / Augusta~$40 Monthly
"Great Xmas Gift" XBox 360 Guitar Hero~Springfied~

1

1

不确定您是否需要使用正则表达式,但如果您不需要,为什么不使用String.split。然后,您可以使用"\\(|\\)"来在括号上拆分字符串,然后从创建的字符串数组中获取各个部分。


这是我的原始方法,但正如您在第一项中所看到的,它有两组括号,而字符串分割无法很好地处理它。 - Nick

1

[编辑] 我不会为这个问题使用正则表达式;相反,我会简单地使用String#lastIndexOf(...)方法来查找最后一个()字符的边界,并从这些值返回子字符串:

public static String[] splitParens(String s) { 
  if (s == null) return null;
  int indexOfLastOpenParen = s.lastIndexOf('(');
  int indexOfLastCloseParen = s.lastIndexOf(')');
  return new String[] { 
    s.substring(0, indexOfLastOpenParen),
    s.substring(indexOfLastOpenParen + 1, indexOfLastCloseParen),
    s.substring(indexOfLastCloseParen + 1)
  };
} 
public static void main(String args[]) throws Exception { 
  String input[] = { 
    "Xbox 360 (black) Elite Console 120GB (Mason City Illinois ) $200",
    "$200 2013 North Trail Camper (RT 202. Manchester, Maine) $224/mo.",
    "Snowmobile Bike trailers (Winthrop / Augusta) $40 Monthly",
    "\"Great Xmas Gift\" XBox 360 Guitar Hero (Springfied)"
  };
  Pattern p = Pattern.compile("\\(([^\\)]+)\\)");
  for (String s : input) { 
    System.out.println(Arrays.asList(splitParens(s)));
  }
  // =>
  // [Xbox 360 (black) Elite Console 120GB , Mason City Illinois ,  $200]
  // [$200 2013 North Trail Camper , RT 202. Manchester, Maine,  $224/mo.]
  // [Snowmobile Bike trailers , Winthrop / Augusta,  $40 Monthly]
  // ["Great Xmas Gift" XBox 360 Guitar Hero , Springfied, ]
}

当然,需要进行更多的错误检查(例如,如果没有()怎么办?)。


它需要在最后一个()处分割,而不是第一个。 - Peter Lawrey
是的,第一行分割了,所以黑色将是位置和精英控制台... $200 是价格,我正在尝试避免。 - Nick
@Nick:明白了,我刚刚更新了我的答案,但看起来PeterLawrey比我更快! - maerics
好主意,你可能也想对字段进行trim()处理。 ;) - Peter Lawrey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接