【问题标题】:Reorder names with java regex使用 java 正则表达式重新排序名称
【发布时间】:2014-08-10 03:41:29
【问题描述】:

我有一系列名字的形式:

  1. 史密斯,约翰·沃尔特
  2. 小詹姆斯·塞缪尔·琼斯

我正在努力寻找一个正则表达式,它可以让我将每个元素提取为单独的文本元素。我的代码目前如下所示:

Pattern pattern = Pattern.compile("(.+?), (.+?) (.*)(?:, )((.*))?$");
Matcher matcher = pattern.matcher( name2 );

System.out.println( matcher.find() );     
System.out.println( matcher.groupCount() );
System.out.println( matcher.group( 1 ) );  
System.out.println( matcher.group( 2 ) );  
System.out.println( matcher.group( 3 ) );  
System.out.println( matcher.group( 4 ) )

此模式匹配第二种名称格式,允许我提取其组成部分但不匹配第一种(无疑是由于向前看)。当我将前瞻设为可选 ((.+?), (.+?) (.*)(?:, )?((.*))?$) 时,我匹配第一个名称格式,但当我使用第二个名称格式时,我捕获了中间名和后缀。我确信有一种简单的方法可以完成我所追求的目标,但在正则表达式方面我相对缺乏经验。

提前感谢您的帮助!

【问题讨论】:

  • 使用String.split()方法怎么样:name2.split(",")
  • 您希望从给出的示例中提取哪些元素?此外,您想要的最终结果(“重新排序”之后)是什么?
  • 这种问题已经被问过很多次了。如果您没有固定格式 - 尝试解析它是无用的,并且如果您有特定格式 - 删除所有逗号/点/等并使用简单的 split() 提取名字/姓氏(超过空格)。试图找到一个灵丹妙药的正则表达式是浪费时间。

标签: java regex lookahead


【解决方案1】:

您的模式中没有前瞻。带有(?:pattern) 的模式称为非捕获组。它们就像常规匹配一样,只是它们允许您将括号中的内容分组,而无需为其分配group(n) 编号。这很好,因为您确实不需要为此目的进行前瞻。

你需要说的是逗号和后缀,作为一个组,是可选的。为此,请将逗号和后缀放在括号中(您可以在此处使用(?:),并在整个组之后放置?

Pattern pattern = Pattern.compile("(.+?), (.+?) (.*)(?:, (.*))?$");

但是,这并不能解决您的第二个问题,即第三组 (.*) 将消耗尽可能多的字符。由于最后一部分(逗号 + 后缀)是可选的,因此正则表达式发现它可以消耗字符串的其余部分并仍然获得匹配。要解决这个问题,你可以让它成为一个不情愿的匹配,就像你对前两组所做的那样:

Pattern pattern = Pattern.compile("(.+?), (.+?) (.*?)(?:, (.*))?$");

或者只是告诉(.*) 不要匹配任何逗号:

Pattern pattern = Pattern.compile("(.+?), (.+?) ([^,]*)(?:, (.*))?$");

注意:我还没有测试过这些。

【讨论】:

    猜你喜欢
    • 2017-01-30
    • 1970-01-01
    • 2012-12-18
    • 1970-01-01
    • 2021-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-26
    相关资源
    最近更新 更多