2

我需要一个正则表达式来从 GEDCOM 文件中提取名称。格式为:

弗雷德约瑟夫/史密斯/

以 / 为界的文本是姓氏,Fred Joseph 是名字。复杂之处在于姓氏可能在文本中的任何位置,也可能根本不存在。我需要一些可以提取姓氏并将其他所有内容作为名字的东西。

据我所知,我已经尝试使用 ? 预选赛但无济于事:

到目前为止我所拥有的

如您所见,它有几个问题:如果姓氏丢失,则不会捕获任何内容,名字有时会有前导和尾随空格,当我真的想要 2 个时,我有 3 个捕获组。如果姓氏的捕获组不包含“/”字符。

任何帮助将非常感激。

4

5 回答 5

3

对于您的最后一行,我不确定是否有办法将第 1 组和第 3 组加入一个组。

这是我提出的解决方案。它不会捕获名字周围的空格。

^(?:\h*([a-z\h]+\b)\h*)?(?:\/([a-z\h]+)\/)?(?:\h*([a-z\h]+\b)\h*)?$

要正确匹配名称,请注意使用不敏感标志,如果一次测试所有行,请使用多行标志。

查看演示

解释

  • ^行首
  • (?:\h*([a-z\h]+\b)\h*)?第一个匹配 0 次或 1 次的非捕获组:
    • \h*0 个或多个水平空格
    • ([a-z\h]+\b)捕获一组字母和空格,但在最后一个单词的末尾停止
    • \h*匹配可能的剩余空间而不捕获
  • (?:\/([a-z\h]+)\/)?第二个非捕获组,匹配 0 次或 1 次捕获组中由斜杠包围的名称
  • (?:\h*([a-z\h]+\b)\h*)?第三个非捕获组与第一个相同,捕获第三组中的名称。
  • $队伍的尽头
于 2017-02-18T10:01:11.020 回答
0

为您的要求

([A-z a-z /])+\w*

样本

于 2017-02-18T09:18:10.953 回答
0

我不确定我是否遵循用于提取数据的语言,但根据您目前所拥有的,您只需添加“?”:

(.*)(\/?.*\/?)(.*)

并不是说这不会为您提供每个名称的分组,因为某些解决方案将在一个组中具有多个名称

编辑:

扩展 Niitaku 解决方案并查看将每个人的名称放在自己的组中,您可以使用:

^\s*(?:\/?([a-z]+)\/?)\s*(?:\/?([a-z]+)\/?)\s*(?:\/?([a-z]+)\/?)\s*$

正如所解释的,如果使用像 ruby​​ 这样的语言,它只是:

ruby -pe '$_ = $_.scan(/\w+/)' file
于 2017-02-18T09:29:07.563 回答
0

希望这可以帮助 (.\*?)\\/(.\*?)\\/(.\*)

于 2017-02-18T09:57:29.693 回答
0

试试这个:^([^/]*)(/[^/]+/)?([^/]*)$

这符合以下条件:

  • ^字符串开头(或使用多行修饰符开头)
  • ([^/\n]*)/零次或多次换行 以外的任何内容- 这被捕获为第 1 组
    • (/[^/\n]+/)?单个/后跟一个或多个非/或换行字符,然后是单个“/”字符 - 这被捕获为组 2,并且是可选的
    • ([^/\n]*)/除了新行零次或多次以外的任何内容- 这被捕获为第 3 组
    • $字符串结尾(或带有多行修饰符的行尾)

您可以在此处查看示例文本的实际操作:https ://regex101.com/r/9kmKpy/1

要不捕获斜线,您可以通过将 ?: 添加到第二组括号来添加非捕获组,然后在斜线之间添加另一对: ^([^\/\n]*)(?:\/([^\/\n]+)\/)?([^\/\n]*)$

https://regex101.com/r/9kmKpy/2

于 2017-02-18T11:16:32.447 回答