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