鉴于以下价格列表,我试图弄清楚如何仅规范化/提取数字。

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

  • 我正在寻找 sedgrepawk 以获得可移植且高效的解决方案。我应该如何解决这个问题?

    我找到了 similar question ,但我不知道如何使用 sed 尝试以下正则表达式:
    ^\d+(,\d{1,2})?$
    

    编辑:是的,我的输入格式可能有点奇怪,因为它是拼接页面的结果。

    最佳答案

    您可以使用以下 shell 脚本:

    #/bin/sh
    grep -v '\.\d\+\.' | # get rid of lines with multiple dots within the same number
    grep -v '\.\d\d\d\+' | # get rid of lines with more than 2 digits after .
    sed -e 's/\(.*\.[0-9][0-9]\).*$/\1/' | # remove anything after last .NN
    sed -e 's/^.* \([0-9][0-9][0-9][0-9]\)\./\1./' | # "* NNNN." => "NNNN."
    sed -e 's/^.* \([0-9][0-9]\)\./\1./' | # "* NN." => "NN."
    sed -e 's/^.* \([0-9]\)\./\1./' | # "* N." => "N."
    sed -e 's/^\(.*\)[ ,]\(\([0-9]\)\{3,\}\)\./\1\2./g' | # "*,NNN." or "* NNN." => "*NNN."
    sed -e 's/^\(.*\)[ ,]\(\([0-9]\)\{6,\}\)\./\1\2./g' | # "*,NNNNNN." or "* NNNNNN." => "*NNNNNN."
    sed -e 's/^\(.*\)[ ,]\(\([0-9]\)\{9,\}\)\./\1\2./g' | # "*,NNNNNNNNN." or "* NNNNNNNNN." => "*NNNNNNNNN."
    grep -o '\d\+\.\d\d' # print only the price
    

    对于由空格或 , 以 3 位为一组的数字,此解决方案最多适用于 . 之前的 9 位数字。如果您需要提取更大的价格,只需添加更多行,将正则表达式中的数字增加 3。;-)

    将它放在一个名为 extract_prices 的文件中,使其可执行( chmod +x extract_prices )并运行它: ./extract_prices < my_list.txt
    使用以下输入在 OS X 上测试:
    CA$1399.00
    &#36;1399.11
    $1,399.22<
    Z$1 399.33
    Z$12 777 666.34   # <-- additonal monster price
    $1399.44#
    C$ 1399.55
    1,399.66
    1399.77
    ,1399.88
    25 1399.88
    399.99
    88.88 99.99
    .1399.88
    666.000
    

    这会生成以下输出:
    1399.00
    1399.11
    1399.22
    1399.33
    12777666.34
    1399.44
    1399.55
    1399.66
    1399.77
    1399.88
    1399.88
    399.99
    99.99
    

    关于regex - shell 正则表达式 : Extract prices,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34325802/

    10-13 04:55