我有一组像这样的字符串:
[
"ERDF : EUR 2.7 million",
"ERDF : EUR 961 000",
"ERDF: 7 305 000 DKR (+/- EUR 974 000) ",
"FEOGA: 40 826 EUR",
"49 % of eligible costs",
"ERDF contribution: 64%",
"FEDER (Objectif 5b 1994-1996) 60 979 euros (400 000 FRF)",
"FEDER, Objectif 2, 1994 - 1999: 1 116 000 EUR",
"EUR 8.000.000",
"EUR 7.200.000",
"EUR 4.200.000",
"4.2 million euros",
"EUR 0.2 million",
"EUR 0.6 million",
"FEDER: 830 842 euros (5 450 000 FRF)",
"EUR 7,220,000,000",
"DKR 1 220 000 + DKR 1 380 000 ",
"GBP 150 000" ]
在regex101.com上在线
我想捕获带有eur*
作为前缀或后缀的数字(如果存在,则带有'million')。以下情况应与表达式匹配
10 million euros
EURO 5.000
EUR 100
仅当eur*
在数字前
/(\beur[a-z]*|€)+[\s\d\,\.|million]*\b/gi
答案 0 :(得分:1)
基本答案
我会推荐类似的东西
/(?:eur\w*|€)?\s*([0-9\., ]+)\s*(million)?\s*(?:eur\w*|€)?/i
这会将数字和“百万”识别为两个单独的捕获组,并匹配您给定的每个示例:
EUR 7.200.000
->组1 = 7.200.000
euro 4 000
->组1 = 4 000
EUR 0.2 million
->组1 = 0.2
,组2 = million
Main project: 300 000 EUR
->组1 = 300 000
1998: 43.000.000 euros
->组1 = 43.000.000
这里是您可以使用的live example at Regex101正则表达式。
更完整的答案
现在,也就是说,这个答案与原始请求完全不同,因为它也匹配裸机号码。如果您需要一个绝对仅匹配eur
前后的数字,则需要复制和分割正则表达式,如下所示:
/(?:eur\w*|€)\s*([0-9\., ]+)\s*(million)?|([0-9\., ]+)\s*(million)?\s*(?:eur\w*|€)/i
这正确地捕获了您上面所有的原始示例,但不会捕获裸露的数字。
我也有这种形式的live example on Regex101。
以下是与您提供的the extended dataset相匹配的正则表达式;请注意,它与法郎,百分比,英镑或其他任何不希望有的值都不匹配,但是正确提取了每一欧元。
超越问题
如@blhsing所建议的那样,在包含\b
字边界方面可能会有一定的价值,以使该不与Grandeur 100
之类的东西匹配。这些字边界字符在正则表达式中的eur
之前:
/(?:\beur\w*|€)\s*([0-9\., ]+)\s*(million)?|([0-9\., ]+)\s*(million)?\s*(?:\beur\w*|€)/i
奇怪的特殊情况
Radu问为什么上面的示例与以下示例不正确匹配:
ERDF : EUR 2.7 million
或者,更具体地说,他想知道为什么它只捕获。答案是正则表达式贪婪:它们从左到右捕获,并尽可能快地捕获。因此,正则表达式引擎一看到
EUR
,就可以正确捕获那个作为答案,因为我们已经允许为“数字”!
解决此问题的方法是要求每个“数字”至少以实际的数字开头-以.
或,
或开头不应该被允许。我们可以这样扩展数字部分来做到这一点:
[0-9\., ]+
(这些数字字符中的一个或多个)
[0-9][0-9\., ]*
(仅 一个数字,然后是零个或多个其他字符)因此,扩展的正则表达式不会因为过于贪婪而错误地捕捉到Radu的另一个示例(并且包括单词的边界),这看起来有点丑陋:
/(?:\beur\w*|€)\s*([0-9][0-9\., ]*)\s*(million)?|([0-9][0-9\., ]*)\s*(million)?\s*(?:\beur\w*|€)/i
正则表达式学习
此正则表达式如何工作?它使用了一些原始的基本部分:
(?:...)
,这是一个不可捕获的组:(?:...)
就像括号一样,将事物组合在一起具有优先权,但是实际上并没有捕获其内容作为输出的一部分。?
可选。基于这些知识,我们可以将整个模式(在下面再次复制)分解为逻辑块:
/(?:eur\w*|€)\s*([0-9\., ]+)\s*(million)?|([0-9\., ]+)\s*(million)?\s*(?:eur\w*|€)/i
(?:eur\w*|€)
首先匹配eur...
部分。\s*
匹配可选的空格。([0-9\., ]+)
捕获数字。\s*
(million)?
([0-9\., ]+)
\s*
匹配一些可选的空格。(million)?
\s*
eur...
:(?:eur\w*|€)
答案 1 :(得分:0)
您也可以尝试((?=[\w\s\d\.]+eur)|(?=[\w\s\d\.]+EUR))(eur(os)?|EUR(OS)?|million|\s|\d|\.)+?(?=$|\(|\))