首页 文章

正则表达式多个匹配子字符串

提问于
浏览
3

我有一个应用程序,根据perl正则表达式确定它是否应该显示下拉菜单或简单的输入字段 . 因此,我必须检查正则表达式模式的“外形”和子串 . 为此,我想出了几个解决方案 .

给定输入模式“^(100 | 500 | 1000)$”,这将导致下拉菜单中有三个条目,100,500和1000.我需要一个正则表达式来解析整个模式,以确定它是否是有效列表,以及一个执行实际子字符串匹配的正则表达式,因为我不知道如何多次匹配一个子字符串 . 这是我的正则表达式模式:

^\^\((?:((?:[^\|]|\\\|)+)(?:\||(?:\)\$$)))+

一点点简化,因为这个正则表达式有点模糊:

^\^\((?:([\w\d]+)(?:\||(?:\)\$$)))+

这可以工作,但只存储最后一个子字符串(在给定的情况下为1000)并抛弃其余部分,使用PCRE和在线正则表达式工具进行测试 . 为了得到实际的子串,即下拉菜单字段,我有:

(?:\^\()?((?:[^\|]|\\|)+)(?:\||(?:\)\$$))

再次简化:

(?:\^\()?([\w\d]+)(?:\||(?:\)\$$))

这与子字符串匹配但与其他正则表达式所做的下拉菜单模式语法不匹配(例如,这个也匹配“^(100 |”和子字符串“100”) . 我的问题是:有没有办法合并这些正则表达式只有一个模式匹配1)整个模式语法和2)实际的子串?

提前致谢,

杰里米

P.S . :抱歉,如果这是显而易见的,但我今天对所有这些正则表达式都非常纠结 .

样本数据:

输入正则表达式:^(100 | 500 | 1000)$
语法OK!
匹配的子串:100,500,1000
=>显示下拉菜单

输入正则表达式:^ [0-9a-fA-F] $
语法错了!
=>显示常规输入字段

输入正则表达式:^(foo | bar)$
语法OK!
匹配的子串:"foo","bar"
=>显示下拉菜单

输入正则表达式:^(foo | bar)[0-9] $
语法错了!
=>显示常规输入字段

2 回答

  • 1

    您可以通过两个步骤实现所需 .

    您可以使用此正则表达式来验证格式:

    \^\(\w+(?:\|\w+)*\)\$
    

    Working demo

    enter image description here

    一旦验证了正确的字符串,就可以使用如下函数:

    $str = "^(100|500|1000|2000|3000)$";
    $arr = preg_split ("/\W+/" , $str, -1, PREG_SPLIT_NO_EMPTY);
    print_r($arr);
    

    输出:

    Array
    (
        [0] => 100
        [1] => 500
        [2] => 1000
        [3] => 2000
        [4] => 3000
    )
    
  • 4

    看起来你正在使用PCRE .

    您可以利用 PCRE_DUPNAMES 选项,或者将 (?J) 选项放在模式的前面 .

    此选项使PCRE记住每个捕获组的匹配值,而不是丢弃除最后一个之外的所有内容 . ( this is wrong ,见评论)

    不幸的是,它不受在线测试工具AFAIK的支持 . 我不知道你使用哪种语言,但它也需要一些支持才能让你使用这个功能 .

    来自PCRE docs

    如果要获取给定名称的所有捕获子字符串的完整详细信息,则必须使用pcre_get_stringtable_entries()函数 .

相关问题