数字输入转换的正则表达式...帮忙看看这个能一次匹配吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
firhome
V2EX    程序员

数字输入转换的正则表达式...帮忙看看这个能一次匹配吗?

  •  
      firhome 2014-02-18 10:20:54 +08:00 4174 次点击
    这是一个创建于 4285 天前的主题,其中的信息可能已经有所发展或是发生改变。
    有字符串 '--.3.--.---3'

    前面有N个 -- 的时候 只保留一个

    有点的时候保留距离数字最近的点

    '--.3.--.---3' 转换 -.33

    '-.-3.---.--5---.' 转换 -3.5
    16 条回复    1970-01-01 08:00:00 +08:00
    iptux
        1
    iptux  
       2014-02-18 12:19:48 +08:00
    留个爪,想看答案
    znx5858
        2
    znx5858  
       2014-02-18 13:52:12 +08:00   1
    没领会到gist。“前面有N个 -- 的时候 只保留一个”,中间的“-”需要全部去掉么?
    vibbow
        3
    vibbow  
       2014-02-18 14:02:46 +08:00   1
    '--.3.--.---3' 转换 -.33
    为什么结果不是 -3.3 或者 -.3.3
    ianva
        4
    ianva  
       2014-02-18 14:17:59 +08:00   1
    s/^\(-\)*\(\.\)*-*\([0-9][0-9]*\)/\1\2\3/
    /^-*\./b hasPreDot
    s/^\(-*[0-9][0-9]*\)\(-*\(\.\)*-*\)*/\1\3/
    s/\([0-9][0-9]*\)\(--*\.*-*\)/\1/g
    t
    :hasPreDot
    s/\([0-9][0-9]*\)\(-*\.*-*\)*/\1/g
    gongweixin
        5
    gongweixin  
       2014-02-18 16:36:27 +08:00   1
    我也没理解楼主的意思,“前面有N个 -- 的时候 只保留一个” 保留哪个?“有点的时候保留距离数字最近的点” 离那个数字最近的??'--.3.--.---3' 转换 -.33 为什么'-.-3.---.--5---.' 转换 不是-.35 ?
    gongweixin
        6
    gongweixin  
       2014-02-18 16:37:45 +08:00   1
    .3--.5 结果是什么呢? -.--5 结果是什么呢? 楼主说的不清楚啊。
    firhome
        7
    firhome  
    OP
       2014-02-18 16:46:15 +08:00
    我整理一下.(我题目里第二个有误)

    "如果有负号一定在数字前面,小数点在负号之后(不挨着也可以.) 其余多余的负号都删除掉"

    也就是说:

    .--.3...5 >>> -.35
    ----3...5 >>> -3.5

    --.--3.---5 >>> -.35

    ......3.5 >>> .35

    3....---...5--- >>> 3.5

    为啥可以 -.35 或者 .35 因为js的parseFloat结果是 -0.35 和 0.35
    xierch
        8
    xierch  
       2014-02-18 22:07:31 +08:00
    必须要正则?
    还是写几个 if 吧..
    xierch
        9
    xierch  
       2014-02-18 22:44:28 +08:00
    jakwings
        10
    jakwings  
       2014-02-19 01:46:01 +08:00   1
    真是奇葩的问题。也不说会出现多少段数字。那我默认最多两段。
    要匹配不难,要转换的话肯定得接着用 if 判断一下吧。
    那我用 Javascript 那弱弱的正则表达式来匹配:/^([.\-]*\d+)+[.\-]*$/

    接着可用另一个 Javascript 语句来转换(最多匹配转换两段数字):
    str.replace(/^(?:\.*(-))?[.\-]*?(\.\d+|\d+\.)(?:[.\-]+(\d+)[.\-]*)?$/, '$1$2$3');
    jakwings
        11
    jakwings  
       2014-02-19 01:47:20 +08:00   1
    @jakwings 转换语句更正一下:
    str.replace(/^(?:\.*(-))?[.\-]*?(\.\d+|\d+\.)(?:[.\-]+(\d+))?[.\-]*$/, '$1$2$3')
    jakwings
        12
    jakwings  
       2014-02-19 01:50:46 +08:00   1
    @jakwings 再更正一下:
    str.replace(/^(?:\.*(-))?[.\-]*?(\.\d+|\d+\.|\d+)(?:[.\-]+(\d+))?[.\-]*$/, '$1$2$3');
    jakwings
        3
    jakwings  
       2014-02-19 05:33:47 +08:00   1
    @jakwings 回来回味了一下楼主的题目,发现我还是理解错了?

    最前面有负号则转换出负数,前方(负号后)*任意位置*有点就加上小数点并忽略后面任意位置的点,若前方没有点而后方(数字之前)*任意位置*有点则在后方加上小数点。好吧,我再更正一下转换语句:

    str.replace(/^\.*(-)?(?:-*(\.)[.\-]*(\d+)(?:[.\-]*(\d+))?|[.\-]*(\d+)(?:-*(\.)?[.\-]*(\d+))?)[.\-]*$/, '$1$2$3$4$5$6$7');

    详细解释如下(非 [] 中的空格请忽略):
    @^
    \.*(-)? #检测开头的负号,并且忽略负号前的点
    (?: #进入多种模式匹配
    -*(\.)[.\-]* #找到(负号后的)点
    (\d+)(?:[.\-]*(\d+))? #找到小数点后的数字,并忽略其后的点
    | #第二个模式开始
    [.\-]*(\d+) #找到(小数点前的)数字
    (?:-*(\.)?[.\-]*(\d+))? #找到(小数点及其后的)其余数字
    ) #匹配模式结束
    [.\-]* #忽略其后所有无意义字串
    @$

    当然,我不知道会不会出现这样的字串「3---5」,上面会将其转换为「35」。
    jakwings
        14
    jakwings  
       2014-02-19 07:39:08 +08:00   1
    @jakwings 再次修正,关于忽略最负号前的点的:
    str.replace(/^(?:\.*(-))?(?:-*(\.)[.\-]*(\d+)(?:[.\-]*(\d+))?|[.\-]*(\d+)(?:-*(\.)?[.\-]*(\d+))?)[.\-]*$/, '$1$2$3$4$5$6$7');

    顺便,这个正则表达式也不算怎么高效。还不如先简单配置再通过多次替换来转换:
    http://cxg.de/_7d95ff.htm
    ianva
        15
    ianva  
       2014-02-19 10:56:55 +08:00
    我觉得这个还是写个parser靠谱,sed 可以实现条件分支但也太麻烦了,没可读性,一个正则解决基本是没有可读性,各种错误是少不了的
    jakwings
        16
    jakwings  
       2014-02-19 11:24:00 +08:00
    =_= 楼主真厚道啊,给我的每条回复送了感谢(铜币)。今天被送感谢 V2EX 貌似没有提醒(难道频繁送同一人感谢会被当骚扰取消通知?)……
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2445 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 15:49 PVG 23:49 LAX 07:49 JFK 10:49
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86