【发布时间】:2016-03-23 09:39:58
【问题描述】:
鉴于以下价格列表,我试图弄清楚如何仅规范化/提取数字。
INPUT DESIRED_OUTPUT
CA$1399.00 1399.00
$1399.11 1399.11
$1,399.22< 1399.22
Z$1 399.33 1399.33
$1399.44# 1399.44
C$ 1399.55 1399.55
1,399.66 1399.66
1399.77 1399.77
,1399.88 1399.88
25 1399.88 1399.88
399.99 399.99
88.88 99.99 99.99 (if >2 matches on one line, only the last one matters)
.1399.88 DO NOT MATCH (not a price; too many ".")
666.000 DO NOT MATCH (not a price: too many 0's)
我认为从它们的共同点开始是个好主意:
- 价格始终包含
.NN,但绝不包含.NNN
经过进一步检查,其他规则变得明显:
-
.NN前面必须有一个或多个digits。 -
NNN.NN可以在,、或简单的digit前面,但仅此而已。 -
.NN之后和*N.NN之前的任何内容都标志着比赛的结束。 - 最后,正则表达式需要考虑
1,399.66(1399.66) 之类的逗号,以确定它是否是价格,然后去掉它们。1, 399.66,例如不等于1399.66:应该是399.66。
我正在寻找sed、grep 和awk 寻找可移植且高效的解决方案。我应该如何解决这个问题?
我找到了similar question,但我不知道如何使用sed 尝试以下正则表达式:
^\d+(,\d{1,2})?$
编辑:是的,我的输入格式可能有点奇怪,因为它是抓取页面连接的结果。
【问题讨论】:
-
见unix.stackexchange.com/a/138937推荐
grep -o。您的输入格式非常尴尬 -Z$1 399.33应该匹配空格前的数字,但25 1399.88不应该匹配空格前的数字?为什么——根据什么规则可以对这种区别进行编码?程序和数据的其余部分是什么样的 - 你可以进行清理运行或多次运行吗? -
4、8、12等位置的空格/逗号 (RTL)。是可以接受的,所以1 399.88、1 333 399.88和1 133 333 399.88都可以。匹配Z$1 399.33应该没什么大不了的;数字一出现 $ 就结束(再次读取 RTL)。 -
棘手的情况:
.1399.98不能匹配,而1 399.98对应1399.98。但是那么.1 399.98呢?那么空间是否很大,以至于匹配且价格为399.98?我认为要求应该是通过提取.1作为标记来解决案例,其中尾随空格终止分数。下一个数字标记是399.98:好价钱。 -
您使用什么严格可移植的 Unix 工具来抓取这些数据?
-
好点。人类常识告诉我们,
.1 399.98独立存在就是1399.98,但在其他情况下,这样的宽松规则可能会导致误报,这就是我拒绝.1399.88的原因。我不确定如何解决这个问题,但.1 399.98无论如何都不太可能。 @Kaz 卷曲。我使用卷曲。