我正在尝试仅从 openrefine 中的文本列中提取电子邮件。有些单元格只有电子邮件,但其他单元格有名称和电子邮件john doe <john@doe.com>
格式。我一直在使用以下 GREL/regex,但它不会返回整个电子邮件地址。对于上面的例子,我得到了["n@doe.com"]
value.match(
/.*([a-zA-Z0-9_\-\+]+@[\._a-zA-Z0-9-]+).*/
)
任何帮助深表感谢。
我正在尝试仅从 openrefine 中的文本列中提取电子邮件。有些单元格只有电子邮件,但其他单元格有名称和电子邮件john doe <john@doe.com>
格式。我一直在使用以下 GREL/regex,但它不会返回整个电子邮件地址。对于上面的例子,我得到了["n@doe.com"]
value.match(
/.*([a-zA-Z0-9_\-\+]+@[\._a-zA-Z0-9-]+).*/
)
任何帮助深表感谢。
被n
捕获是因为您.*
在捕获组之前使用,并且由于它可以贪婪地匹配除换行符之外的任何 0+ 字符,因此在回溯期间唯一可以落在第 1 组中的字符是之前的字符@
。
如果您可以获得部分匹配,请摆脱.*
并使用
/[^<\s]+@[^\s>]+/
查看正则表达式演示
细节
[^<\s]+
- 1 个或多个字符,而不是<
空格@
- 一个@
字符[^\s>]+
- 除空格和 . 以外的 1 个或多个字符>
。Python/Jython 实现:
import re
res = ''
m = re.search(r'[^<\s]+@[^\s>]+', value)
if m:
res = m.group(0)
return res
还有其他方法可以匹配这些字符串。如果您需要完整的字符串匹配.*<([^<]+@[^>]+)>.*
,.*
则不会吞噬名称,因为它会在强制<
.
如果某些单元格只包含电子邮件,最好使用@wiktor-stribiżew 的部分匹配。在 Open Refine 的开发版本中,现在有一个value.find()
功能可以做到这一点,但要到下一个版本(2.9)才会正式实现。同时,您可以使用 Python/Jython 而不是 GREL 来重现它:
import re
return re.findall(r"[^<\s]+@[^\s>]+", value)[0]
结果 :