【问题标题】:How to parse variable length command line arguments with regex?如何使用正则表达式解析可变长度命令行参数?
【发布时间】:2019-05-31 15:02:15
【问题描述】:

我有大量文件,每个文件都包含一个带有可变数量参数的 bash 命令。我需要用相应的 API 调用替换这些。

文件中的示例 bash 命令(注意:“-p”参数的数量不同,有些没有):

./some_script.sh http://some.server.com -p a=value -p b=value -p c=value

对应的API调用示例

http://some.server.com/api/some/endpoint?a=value&b=value&c=value

我的问题是我似乎无法对每个参数进行分组,因为参数的数量是可变的。

基本正则表达式(这将匹配上面的示例,但仅分组第一个参数):

.\/some_script.sh\s([\w\/:\.]*)(\s-\w\s[\w=]*)

我试过了:

.\/some_script.sh\s([\w\/:\.]*)(\s-\w\s[\w=]*)*

但是,这似乎只对最后一个参数进行分组。 (用 regex101 测试)

理想情况下,我希望这个正则表达式能够在这些文件中对不定数量的参数进行分组,以便我可以轻松地将命令重新构建为 API 调用。

如果需要更详细的信息,请告诉我,欢迎提出任何建议。

【问题讨论】:

    标签: regex pcre regex-lookarounds regex-group regex-greedy


    【解决方案1】:

    你需要使用 \G 锚

    /(?|\.\/some_script\.sh\s([\w\/:.]*)|(?!^)\G())\s-(\w)\s([\w=]*)/
    

    https://regex101.com/r/0151qC/1

    展开

     (?|                           # Branch reset
          \. /some_script \. sh         # First, find the script name
          \s 
          ( [\w/:.]* )                  # (1), url
    
       |                              # or,
          (?! ^ )
          \G                            # Start where last left off
          ( )                           # (1), blank url
    
     )
    
     \s - 
     ( \w )                        # (2), - 'p'
     \s 
     ( [\w=]* )                    # (3), 'a=value'
    

    【讨论】:

      【解决方案2】:

      在这里,也许我们可以找到另一种方法,并逐步从输入中收集我们想要的数据。然后,我们可能会从类似于以下的表达式开始:

      .+\.sh.+?(https?:\/\/[^\s]*)|\s+-[a-z]+\s+([\w=]+)
      

      这里有我们的链接:

      (https?:\/\/[^\s]*)
      

      和我们的变量:

      ([\w=]+)
      

      用逻辑 OR 改变。

      如果需要,我们还可以修改和添加其他边界或减少我们的边界。

      DEMO

      测试

      这个 sn-p 只是显示了捕获组是如何工作的:

      const regex = /.+\.sh.+?(https?:\/\/[^\s]*)|\s+-[a-z]+\s+([\w=]+)/gm;
      const str = `./some_script.sh http://some.server.com -p a=value -p b=value -p c=value
      `;
      let m;
      
      while ((m = regex.exec(str)) !== null) {
          // This is necessary to avoid infinite loops with zero-width matches
          if (m.index === regex.lastIndex) {
              regex.lastIndex++;
          }
          
          // The result can be accessed through the `m`-variable.
          m.forEach((match, groupIndex) => {
              console.log(`Found match, group ${groupIndex}: ${match}`);
          });
      }

      正则表达式电路

      jex.im 可视化正则表达式:

      【讨论】:

      • 完美!非常感谢 Emma 的快速回答!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-04
      • 1970-01-01
      • 1970-01-01
      • 2019-09-21
      • 1970-01-01
      • 2012-05-17
      相关资源
      最近更新 更多