我正在尝试编写一个替换函数,它将接受一个字符串,如果它将它标识为一个数字,则会将其更改为标准格式的数字(在大多数语言中都是可解析的)
是否可以使用单个正则表达式来实现?最终有几个后续的替代品?
我在用
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' <- 这些被证明可以解析为 float
我可能处理的可能字符串,以及我想用什么替换它们:
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 除外)取消字符串作为数字的资格(因此不会进行替换)
最佳答案
使用单个正则表达式可能是不可能的。
问题在于您必须首先将字符串标识为“有效数字”(可行),然后确定要删除的字符串的子部分(在单个正则表达式中不可行)。
幸运的是,您正在编写一个函数,因此如果您愿意根据多个正则表达式检查字符串,这里有一些可以满足您的要求。请注意,所有这些都假设您只传递一个数字,而不是其他任何东西。
千位分隔符^-?\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+%$
(我将假设如果最后有 %
,无论如何它都是小数 - 正则表达式将 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!
祝你好运!
关于正则表达式:将数字字符串更改为标准可解析格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57077129/