Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 正则表达式匹配1或2个实例_Regex_Elixir_Pcre - Fatal编程技术网

Regex 正则表达式匹配1或2个实例

Regex 正则表达式匹配1或2个实例,regex,elixir,pcre,Regex,Elixir,Pcre,我有以下结构的文本: 书名:软件工程;作者:约翰;作者:史密斯; 书名:设计模式;作者:傅;作者:巴尔 元素分离器是 book_name元素后面可以有两个author元素 可能有2到10本书 一本书至少应有一位作者,但最多应有两位作者 我想摘录每本书的书名和作者 我使用.scan方法尝试了regex(它收集所有匹配项): 但它不能正确地收集作者。它只收集这本书的第二作者。 有人能帮你解决这个问题吗?在许多引擎中,包括Elixir的引擎,你不能像那样重复多个捕获组,并得到每个重复组的结果-你只能得

我有以下结构的文本:

书名:软件工程;作者:约翰;作者:史密斯; 书名:设计模式;作者:傅;作者:巴尔

元素分离器是

book_name元素后面可以有两个author元素

可能有2到10本书

一本书至少应有一位作者,但最多应有两位作者

我想摘录每本书的书名和作者

我使用
.scan
方法尝试了regex(它收集所有匹配项):

但它不能正确地收集作者。它只收集这本书的第二作者。
有人能帮你解决这个问题吗?

在许多引擎中,包括Elixir的引擎,你不能像那样重复多个捕获组,并得到每个重复组的结果-你只能得到任何给定重复捕获组的最后一个结果。而是分别写出每个可能的组,然后过滤掉空匹配项:

book_name:(.+?;)author:(.+?);(?:author:(.+?);)?

您不需要正则表达式,可以使用:

输出:

iex> Book.extract(text)
[{"SoftwareEngineering", "John", "Smith"}, {"DesignPatterns", "Foo", "Bar"}]
为了简单起见,我假设总是有两位作者。最后一个枚举可以替换为这个枚举,它处理没有第二作者的情况:

|> Enum.map(fn
  [title, _, author1] -> {title, author1, nil}
  [title, _, author1, _, author2] -> {title, author1, author2}
end)
模式的这部分
(author:.+?;){1,2}
重复1-2次
author
,包括直到分号的后续内容,但重复这样的捕获组只会给出最后一个捕获组。可能会有帮助

与使用非贪婪量词
*?
不同,您不能匹配重复与分号不匹配的否定字符类
[^;]+

您还可以使用捕获组和
author
的反向引用。这本书的名字在第1组中,第3组中第一作者的名字和第4组中可选的第二作者的名字

book_name:([^;]+);(author):([^;]+);(?:\2:([^;]+);)?
那会匹配的

  • 书名:
    按字面意思匹配
  • ([^;]+)第1组匹配不
    然后匹配
  • (作者):
    Group 2
    author
  • ([^;]+)第3组匹配不
    然后匹配
  • (?:
    非捕获组
    • \2:
      反向引用组2中捕获的内容
    • ([^;]+);
      第4组匹配不匹配
      然后匹配
  • )?
    关闭非捕获组并将其设置为可选

|> Enum.map(fn
  [title, _, author1] -> {title, author1, nil}
  [title, _, author1, _, author2] -> {title, author1, author2}
end)
book_name:([^;]+);(author):([^;]+);(?:\2:([^;]+);)?