V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yazoox
V2EX  ›  正则表达式

请教一个正则表示式,/\d*[A-Z]*|\?/ 为什么不能选出 bAseline ?

  •  
  •   yazoox · 2020-06-17 18:07:34 +08:00 · 1958 次点击
    这是一个创建于 1655 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Javascript

    在 chrome console 中测试:

    "bAseline".match(/\d*[A-Z]*|\?/)
    
    ["", index: 0, input: "bAseline", groups: undefined]
    

    需求: regex = /\d*[A-Z]*|?/

    3P 返回 3P

    3 返回 3

    Google 返回 G

    GOogle 返回 GO

    bAseline 返回 A

    ? 返回 ?

    调用 string.match 方法!

    const s = "bAseline";
    const res = s.match(/\d*[A-Z]*|\?/);
    

    如果 /\d*[A-Z]|?/ =》 /\d[A-Z]+|?/ 即把 A-Z 后面的*改成+号的话,bAseline 能够通过,但是 纯数字 比如 3 又不行了。

    还是说,我不应该用这个方法?

    谢谢!

    第 1 条附言  ·  2020-06-17 19:34:27 +08:00

    再明确一下需求,

    function getChars(text) {
      const regex = '...';
      const item = text.match(regex);
      return item;
    }
    

    给定一个字符串,经过匹配,然后返回匹配的第一个的字符串:

    1. 单独一个大写字母或者连续的大写字母,

    getChars("GOogle") => GO getChars("Google") => G getChars("bAseline") => A

    1. 如果只有一个单独数字

    getChars("3") => 3

    1. 单独数字+大写字母

    getChars("3Protocol") => 3P

    1. 选出单一问号

    getChars("?") => ?

    现在,就是再想那个regex该怎么写?或者string.match这个方法的使用有问题?等等。

    8 条回复    2020-06-17 23:27:03 +08:00
    yazoox
        1
    yazoox  
    OP
       2020-06-17 18:20:53 +08:00
    再明确一下需求:
    给定一个字符串,把
    1. 连续的大写字母选出来, 比如:3Protocol => 3P, GOogle => GO, Google=>G, bAseline=>A
    2. 选出单一数字,比如:3 => 3
    3. 选出单一问号,比如:?=> ?
    woodensail
        2
    woodensail  
       2020-06-17 18:47:33 +08:00
    你这里有几个问题,首先不应该用*,*可以匹配到空字符串,这个对你而言毫无意义。
    其次没加括号,导致组没有生效。
    另外,不知道你的具体需求是什么,看到 3P 这个例子,似乎是要求全部匹配。不清楚有没有组必须连续的要求,如果没有就得加上参数 g,然后 join 。
    最终 "?bAseline1".match(/(?:\d+|[A-Z]+|\?)/g).join('') === "?A1"
    woodensail
        3
    woodensail  
       2020-06-17 18:49:47 +08:00
    这个实现的效果实际上是挑出里面所有的数字和大写字母以及问号,连不连续无所谓。
    我只能这么理解你的需求了,要不然用例里面 3P 那条没法解释
    ruoxin123
        4
    ruoxin123  
       2020-06-17 18:50:17 +08:00
    "3ProtocolGOogleGooglebAseline".match(/[\dA-Z?]+/g) 试试这个

    需求没写清楚, 1A1 满足需求吗
    yazoox
        5
    yazoox  
    OP
       2020-06-17 19:35:05 +08:00
    @woodensail @ruoxin123
    APPEND 更新了一下需求,再帮忙瞧一眼?
    谢谢。
    yazoox
        6
    yazoox  
    OP
       2020-06-17 21:20:14 +08:00
    问题暂时解决了,方案如下:
    const regex = /\?|\d*[A-Z]+|\d{1}/
    const res = "text_here".match(regex);
    woodensail
        7
    woodensail  
       2020-06-17 22:36:47 +08:00
    @yazoox 基本正确,有些小优化,第一个\d 后面改用问号,以避免匹配多个数字。第二个\d 后面的{1}去掉,固定匹配一个不用加范围。
    /\?|\d?[A-Z]+|\d/
    xiangyuecn
        8
    xiangyuecn  
       2020-06-17 23:27:03 +08:00   ❤️ 1
    用 if else +简单正则 就不香吗?一定要写一个难以维护的晦涩超长正则?

    console.log("超难维护的一坨正则,一坨一坨的:")
    exp=/@(?:(\d)|(\?)|(?:\w*?)(\d?[A-Z]+)(?:\w*))(?=@)/g;

    arr=["BEGIN","GOogle","Google","3","3Protocol","?","abcd","345","?DD","6FIND0End"]

    while(m=exp.exec("@"+arr.join("@")+"@"))console.log(m[1]||m[2]||m[3]||m[4]||m[5]||"")


    console.log("简单易维护,逻辑条理清晰:")
    for(var i=0;i<arr.length;i++){
    str=arr[i]
    val="";
    if(str=="?"){
    val=str
    }else if(str.length==1 && /\d/.test(str)){
    val=str
    }else if(/^\w*?(\d?[A-Z]+)\w*$/.test(str)){
    val=RegExp.$1
    }
    if(val){
    console.log(val)
    }
    }
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2661 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 120ms · UTC 15:12 · PVG 23:12 · LAX 07:12 · JFK 10:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.