正则表达式:搜索不属于单词的数字(整数、浮点数)
RegEx: Searching for numbers (int, float) that are NOT part of a word
我希望我们这里有一些正则表达式专家可以帮助我——一个正则表达式新手——解决问题。
我知道有些人会想知道关于这个问题的一些背景信息:
正则表达式风格:基本正则表达式,使用 REGEXP_REPLACE 函数在 Vertica 数据库中使用。
我使用的正则表达式运行良好,但有一个例外。
我有一个我正在尝试实施的规则,与从文本中剥离数字有关,其中任何数字都是单词的一部分,例如table5、go2market、33monroe、room222 等被忽略且未过滤。
这是我开始检测数字的方法:
[-+]?[0-9]*\.?[0-9]
这似乎工作得很好,例如包括处理直接相邻的逗号和括号。
但是也检测到所有数字是字母文本的一部分的情况,这不符合它不能是单词的一部分的规则,我所说的单词是指任何字母文本。
因此,在寻找解决方案时,我偶然发现了这个正则表达式,它似乎可以很好地检测数字出现在任何字符串旁边或其中的特定情况:
((?:[a-zA-Z]+[0-9]|[0-9]+[a-zA-Z])[a-zA-Z0-9]*)
我的想法是,也许我可以将其作为反向匹配添加到我的原始正则表达式中,以允许它仍然是 select 独立数字,同时忽略那些属于单词的部分,如下所示:
[-+]?[0-9]^((?:[a-zA-Z]+[0-9]|[0-9]+[a-zA-Z])[a-zA-Z0-9]*)*\.?[0-9]^((?:[a-zA-Z]+[0-9]|[0-9]+[a-zA-Z])[a-zA-Z0-9]*)
然而不幸的是,它打破了独立号码的原始检测。
:(
我希望这里有人可以发现我做错了什么,并帮助我确定正确的解决方案?
提前致谢!
根据 Vertica 文档,正则表达式风格似乎遵循 Perl 语法。在这种情况下,您可以使用负面环视,尤其是负面回溯:(?<!\w)
(前面没有单词字符。)
环视只是测试,不消耗字符。
也可以用negative lookahead来测试正确的部分,(?!\w)
(后面不跟单词字符),不过用单词更简单边界,因为模式以数字结尾 (这也是一个单词字符):
(?<!\w)[-+]?\d*\.?\d+\b
在最坏的情况下,如果你的字符串中有类似 v1.0
的东西并且你想避免它,你可以尝试使用回溯控制动词 (*SKIP)
和 (*FAIL)
. (*FAIL)
强制模式失败并且 (*SKIP)
跳过它之前所有已经匹配的位置。我希望 vertica 支持这些 Perl 正则表达式功能。
类似于:
\p{L}+[-+]?\d*\.?\d+(*SKIP)(*FAIL)|[-+]?\d*\.?\d+(*SKIP)(?!\p{L})
我希望我们这里有一些正则表达式专家可以帮助我——一个正则表达式新手——解决问题。
我知道有些人会想知道关于这个问题的一些背景信息:
正则表达式风格:基本正则表达式,使用 REGEXP_REPLACE 函数在 Vertica 数据库中使用。
我使用的正则表达式运行良好,但有一个例外。
我有一个我正在尝试实施的规则,与从文本中剥离数字有关,其中任何数字都是单词的一部分,例如table5、go2market、33monroe、room222 等被忽略且未过滤。
这是我开始检测数字的方法:
[-+]?[0-9]*\.?[0-9]
这似乎工作得很好,例如包括处理直接相邻的逗号和括号。
但是也检测到所有数字是字母文本的一部分的情况,这不符合它不能是单词的一部分的规则,我所说的单词是指任何字母文本。
因此,在寻找解决方案时,我偶然发现了这个正则表达式,它似乎可以很好地检测数字出现在任何字符串旁边或其中的特定情况:
((?:[a-zA-Z]+[0-9]|[0-9]+[a-zA-Z])[a-zA-Z0-9]*)
我的想法是,也许我可以将其作为反向匹配添加到我的原始正则表达式中,以允许它仍然是 select 独立数字,同时忽略那些属于单词的部分,如下所示:
[-+]?[0-9]^((?:[a-zA-Z]+[0-9]|[0-9]+[a-zA-Z])[a-zA-Z0-9]*)*\.?[0-9]^((?:[a-zA-Z]+[0-9]|[0-9]+[a-zA-Z])[a-zA-Z0-9]*)
然而不幸的是,它打破了独立号码的原始检测。
:(
我希望这里有人可以发现我做错了什么,并帮助我确定正确的解决方案?
提前致谢!
根据 Vertica 文档,正则表达式风格似乎遵循 Perl 语法。在这种情况下,您可以使用负面环视,尤其是负面回溯:(?<!\w)
(前面没有单词字符。)
环视只是测试,不消耗字符。
也可以用negative lookahead来测试正确的部分,(?!\w)
(后面不跟单词字符),不过用单词更简单边界,因为模式以数字结尾 (这也是一个单词字符):
(?<!\w)[-+]?\d*\.?\d+\b
在最坏的情况下,如果你的字符串中有类似 v1.0
的东西并且你想避免它,你可以尝试使用回溯控制动词 (*SKIP)
和 (*FAIL)
. (*FAIL)
强制模式失败并且 (*SKIP)
跳过它之前所有已经匹配的位置。我希望 vertica 支持这些 Perl 正则表达式功能。
类似于:
\p{L}+[-+]?\d*\.?\d+(*SKIP)(*FAIL)|[-+]?\d*\.?\d+(*SKIP)(?!\p{L})