正则表达式:将数字字符串更改为标准可分析格式

时间:2019-07-17 13:32:36

标签: regex number-formatting

我正在尝试编写一个替换函数,该函数将使用字符串,并且如果将其标识为数字,则将其更改为标准格式的数字(在大多数语言中均可解析)

使用单个正则表达式是否有可能实现?最终还有一些后续的替换?

我正在使用

scala org.apache.spark.sql.functions.regexp_replace 

regexp_replace(col(x), "regex that will identify number", "standard format number"))

标准格式示例:“-2421”,“ 22.4536”,“ 6.25367E-08”,“ 6.25367e-08” <-事实证明,这些都是可浮动的

我可能要处理的字符串以及我要替换为的字符串

111,222,333.444 -> 111222333.444
111,222,333,444 -> 111222333444
-1,2 -> -1.2
1,22 -> 1.22
1,222 -> 1222
1,000 -> 1000 (if there are 3 digits after commas, it is thousands separator, not decimal)

数字字符串的末尾可能会有'%',在这种情况下,以上规则适用:

1,22% -> 1.22%

其他符号或字母(例如'6.25367E-08'中的e / E除外)使字符串不符合数字的资格(因此将无法进行替换)

1 个答案:

答案 0 :(得分:0)

使用单个正则表达式可能无法实现。

问题来自于以下事实:您必须首先将字符串标识为“有效数字”(可行),然后标识要删除的字符串的子部分(在单个正则表达式中不可行)。

幸运的是,您正在编写一个函数,因此,如果您愿意针对一个以上的正则表达式检查字符串,则可以满足您的一些要求。请注意,所有这些假设都只是您 传递数字,而没有其他内容。


千位分隔符

^-?\d{1,3}(?:,\d{3})+(?:\.\d+)?$

此正则表达式断言,在行的开头和结尾之间,存在一个可选的负号(一到三位数字),后跟一个重复的非捕获组。此非捕获组是一个逗号,后跟3位数字,并重复一次或多次。末尾的非捕获组是一个可选的小数点,后跟一个或多个数字。请注意,这只会匹配千位分隔符,而不会匹配12之类的无逗号数字。

如果此组匹配,则需要标识并删除逗号。可以使用第二个更简单的正则表达式来完成此操作:,

Try it here!


逗号而不是小数

^-?\d+,(?:(?:\d{1,2})|(?:\d{4,}))$

此正则表达式断言,在行的开头和结尾之间有一个可选的负号,一个或多个数字和一个逗号。然后,正则表达式选择逗号后的1或2位数字,或选择逗号后的> 4位数字(而不是3位,即成千上万!)。如果像例子中那样只关心一个或两位数字的逗号小数,那就是^-?\d+,\d{1,2}$

如果此组匹配,则需要标识逗号,并将其替换为句点。也可以使用正则表达式,

Try it here!


逗号而不是小数,结尾为%

^-?\d+,\d+%$

(我假设如果末尾有%,则无论如何都是小数-regex将1,000%视为1.000%。)

此正则表达式断言,在行的开头和结尾之间有一个可选的负号,一个或多个数字,一个逗号,然后一个或多个数字,后跟一个%符号。

如果此组匹配,则需要识别并删除逗号-您知道该演练。

Try it here!


科学计数法

(您未指定科学计数法应执行的操作,因此此正则表达式匹配逗号或句点。)

^-?\d[.\,]\d+[eE]-?\d+$

此正则表达式断言,在行的开头和结尾之间有一个可选的负号,精确地是一个数字,一个句点或逗号,一个或多个数字,小写字母或大写字母E,可选的负号和一个或多个数字。

我不确定您打算使用此正则表达式做什么,但是我想您现在已经拥有编辑字符串所需的内容。

Try it here!


他们全部在一起

如果您只想看看是否可以将字符串解析为数字。

(?:^-?\d[.\,]\d+[eE]-?\d+$)|(?:^-?\d+,\d+%$)|(^-?\d+,(?:(?:\d{1,2})|(?:\d{4,}))$)|(?:^-?\d{1,3}(?:,\d{3})+(?:\.\d+)?$)

Try it here!


祝你好运!