从一个包含重复字符的奇怪大字符串中提取子字符串

3
我有一系列地址行,格式为:12345某个地址,某个广场|电话号码|姓 名。
例如:
40327 Ocie Camp Apt. 117,Maywood | 1-155-932-2562 x738 | Sauer Meredith
76106 Tomas Highway,Santa Ana | 722.884.5632 | Roberts Westley 19056
Jamarcus Lane,Lawndale | (151)847-7455 x133 | Haag Camille 66724 Slip 12-C,Hoover | 841.047.3195 x69422 | Trantow Danielle 99824 Fisher Locks
#247,Akron | (565)132-9970 x93939 | Wiza Bell
我想仅提取姓氏部分。
我尝试了typical str.substring(str.indexOf("|"), str.indexOf(" ")),但显然这会导致错误的字符串被提取。
你有什么办法可以从这些字符串中获取姓氏吗?

在那个“奇怪的字符串”中是否有不止一个姓氏? - ΦXocę 웃 Пepeúpa ツ
2
编辑了一下 - 它们应该是分开的行。每行一个姓氏。 - Paul12596
这是一个分隔的字符串,所以要拆分字符串并获取正确的单元格:s.split("|")[2]。然后,要仅获取姓氏,因为姓氏可能包含空格,所以无法直接获取。 - AxelH
1
你尝试过使用正则表达式吗? - Oliver Charlesworth
6个回答

1
如果您的数据以以下形式一致地定义,即始终具有以下数据结构:
"12345 Some Address, Some Square|电话号码|姓 名"
那么您可以将每行拆分到管道字符并获取索引2处的元素。
String myString = "12345 Some Address, Some Square|phone number|surname name";
String[] x = myString.split("\\|");
System.out.println(x[2]);

编辑:

如果某些元素改变了顺序,这种方法就行不通了;如果某些元素缺失,这种方法也行不通,因此您需要在处理输入之前进行验证。

编辑2:

另一种方法可以是获取管道|的最后一个索引,并使用String#substring()截断。

int c = myString.lastIndexOf("|");
System.out.println(myString.substring(c + 1));

你可以在split方法中使用int参数来强制规定结果的大小。这至少可以防止在字符串较短的情况下出现OutOfBoundsException异常。正如我在评论中所说,这将返回“姓 名”而不是“姓”,但是如果不添加对接受数据的限制或分隔符,则无法仅获取姓氏的解决方案。 - AxelH
1
这个很好用。数据始终保持一致,所以不必担心坏数据的问题。如果我在其他地方搞砸了,我可以使用他们的名字(姓+名),所以这对我的目的来说是有效的。谢谢!只有姓氏会更好,但全名也可以。 - Paul12596

1
你可以用正则表达式来做这件事。
^.*\|([^\d]+)[^|]*$

演示

代码

System.out.println(s.replaceAll("^.*\\|([^\\d]+)[^|]*$", "$1"));

输出

Sauer Meredith                                                                                                                                                                  
Roberts Westley                                                                                                                                                                 
Haag Camille                                                                                                                                                                    
Trantow Danielle                                                                                                                                                                
Wiza Bell   

完整代码:https://ideone.com/uON0BP


0
我会使用正则表达式来完成这个任务。

代码:

@Test
public void test() {
  String[] lines
    = ("40327 Ocie Camp Apt. 117, Maywood|1-155-932-2562 x738|Sauer Meredith\n" +
       "76106 Tomas Highway, Santa Ana|722.884.5632|Roberts Westley")
          .split("\n");

  Pattern pattern = Pattern.compile("^(?<address>.*?)\\|(?<number>.*?)\\|(?<surname>.*?) (?<name>.*?)$");
  for (String line : lines) {
    Matcher matcher = pattern.matcher(line);
    if(matcher.find()) {
      String surname = matcher.group("surname");
      System.out.println(surname);
    }
  }
}

输出:

Sauer
Roberts


该表达式匹配给定格式的单行文本,您可以轻松访问所需的字符串单个部分。

如果您将来想要访问不同的部分,这也更易于维护。


0

使用 lastIndexOf 方法

该方法返回此对象所表示的字符序列中最后一个出现在小于或等于 fromIndex 的位置的字符的索引,如果在该点之前未出现该字符,则返回 -1。

示例:

String data = "40327 Ocie Camp Apt. 117, Maywood|1-155-932-2562 x738|Sauer Meredith";
System.out.println(data.substring(data.lastIndexOf('|') + 1));

0

这是正则表达式的工作:

    Pattern rx = Pattern.compile("[^\\|]*\\|[^\\|]*\\|\\s*([^0-9]+)");

    String line = "76106 Tomas Highway, Santa Ana|722.884.5632|Roberts Westley 19056";

    Matcher m = rx.matcher(line);
    if(m.find()){
      String surname = m.group(1).trim();
      System.out.println(surname);
    }

这将输出

Roberts Westley

0
试试这个。它会给你只有姓氏的结果。
String address = "40327 Ocie Camp Apt. 117, Maywood|1-155-932-2562 x738|Sauer Meredith";
System.out.println(address.substring(address.indexOf("|", address.indexOf("|") + 1) + 1, address.length()).split(" ")[0]);

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