正则表达式匹配匹配的组并将其存储在数组中

Posted

技术标签:

【中文标题】正则表达式匹配匹配的组并将其存储在数组中【英文标题】:Regex expression to match and store matched groups in an array 【发布时间】:2021-10-13 05:03:06 【问题描述】:
    let str = `!img2.png|width=83.33333333333334%!
    
                 !robot (f05f0216-caf4-4543-a630-99c2477849d5).png|width=400,height=400!
    
             fefeeef         !abc.pdf|width=200!
    
            !dfe.xlx           !abcd.xlx!
    `
    
    let str = str.replace(/\!(.*(jpg|png|gif|pdf|xlx))|(|width=)!\]/gm, function (match, capture) 
   
                let imageConfig = [];
             //match and push in array
                imageConfig.push(file: 'abc.jpg' , width: 100, height:200);
                 
                return str; 
            )
                 
   Expected o/p:-
     imageConfig = [file: 'abc.jpg' , width: 100, height:200, file: 'cdf.pdf' , width: 
                                200, ....]  

这是我尝试过的,但正则表达式没有给出正确的匹配及其匹配的组:-

https://regex101.com/r/V6cA4i/1/

【问题讨论】:

【参考方案1】:

您可以使用此正则表达式来构建您的输出:

/!([^|!]*(?:jpe?g|png|gif|pdf|xlx))(?:\|width=(\d*\.?\d+%?)(?:,height=(\d*\.?\d+%?))?)?!/g

Updated RegEx Demo

代码和演示:

let str = `!img2.png|width=83.33333333333334%!
    
                 !robot (f05f0216-caf4-4543-a630-99c2477849d5).png|width=400,height=400!
    
             fefeeef         !abc.pdf|width=200!
    
            !dfe.xlx           !abcd.xlx!`;
            
var re = /!([^|!]*(?:jpe?g|png|gif|pdf|xlx))(?:\|width=(\d*\.?\d+%?)(?:,height=(\d*\.?\d+%?))?)?!/g;
    
let m;
let imageConfig = [];

while ((m = re.exec(str)) !== null) 
  imageConfig.push(file: m[1] , width: (m[2] || ''), height: (m[3] || ''));

console.log(imageConfig);

【讨论】:

感谢您的回答,!abcd.xlx! .这种情况也应该有效。 当然,检查我更新的答案和新的演示【参考方案2】:

该 |需要转义

您必须转义“宽度”之前的| 字符:

更正的正则表达式:

!(.*(jpg|png|gif|pdf|xlx))\|(width=.+)!

您不必根据 regex101 在开头转义 !。如果您的正则表达式方言需要,请随时再次添加\!

可选宽度

如果只给出高度,我们应该检查给定的宽度或高度:

!(.*(jpg|png|gif|pdf|xlx))(\|((width|height)=.+)!)?

【讨论】:

表达式有效,但分组元素只能包含 (abc.png) 或 (width=200) 或 (height=100) 如果您需要高度可选,您必须将(width|height) 组合在一起,否则| 将不起作用。最后一个? 检查|width 是否存在,否则您的最后一个示例将不起作用。您必须在整个表达式周围使用一个组。 AFAIK 正则表达式组将始终在结果中产生一个条目,即使您不需要它。【参考方案3】:

以下方法使用了两个正则表达式的组合,一个用于检索/matching the raw file data ...

/[!"]+([^!"]+)[!"]/gm

...第二个是为了help processing the final data structure ...

/^(?<fileName>[^.]+\.(?:jpg|png|gif|pdf|xlx))(?:\|(?:width=(?<width>.*?))?,?(?:height=(?<height>.*?))?)?$/

两个 reg 表达式都使用 Capturing groups,第二个通过 named groups 执行它,以便仅通过 Destructuring assignments 创建最终数据结构,其中后者仅用于分配像 widthheight 这样的字段以防它们实际上可以被检索到。

有 3 个示例日志记录,逐步推进数据处理,以便了解所有涉及的数据处理步骤...

const sampleText = `!img2.png|width=83.33333333333334%!

             "!robot (f05f0216-caf4-4543-a630-99c2477849d5).png|width=400,height=400!" 

                  "!abc.pdf|width=200!"

        "!dfe.xlx"
  !"dfe.gif|height=400!"`;

// [https://regex101.com/r/XLNGBp/1]
const regXRawFileData = (/[!"]+([^!"]+)[!"]/gm);

// [https://regex101.com/r/XLNGBp/3]
const regXFileData = (/^(?<fileName>[^.]+\.(?:jpg|png|gif|pdf|xlx))(?:\|(?:width=(?<width>.*?))?,?(?:height=(?<height>.*?))?)?$/);

console.log(
  'match all data ...',

  Array.from(
    sampleText.matchAll(regXRawFileData)
  ).map(([match, rawData]) => rawData)
);
console.log(
  'match and filter all valid raw file data ...',

  [...sampleText.matchAll(regXRawFileData)]
    .map(([match, rawData]) => rawData)

    .filter(str => regXFileData.test(str))
);
console.log(
  'match, filter and map all valid file data ...',

  [...sampleText.matchAll(regXRawFileData)]
    .map(([match, rawData]) => rawData)

    .filter(str => regXFileData.test(str))
    .map(str => 
      const  fileName:file, width, height  = regXFileData.exec(str).groups;
      return 
        file,
        ...(width &&  width  || ),
        ...(height &&  height  || ),
      ;
    )
);
.as-console-wrapper  min-height: 100%!important; top: 0; 

【讨论】:

以上是关于正则表达式匹配匹配的组并将其存储在数组中的主要内容,如果未能解决你的问题,请参考以下文章

如何使用正则表达式查找特定匹配项并将它们放入字符串数组中?

正则表达式 - 匹配相同模式的组

正则表达式 Match.Value 返回整个值,而不是匹配的组

java正则表达式匹配IP地址和端口号作为捕获的组

Java中匹配URL的正则表达式

正则表达式中 ?,+,*,{}的运用