Manzer A
Manzer A

Reputation: 3806

Regex expression to match and store matched groups in an array

    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}, ....]  

This is what I tried, but regex is not giving correct match and its matched group:-

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

Upvotes: 1

Views: 87

Answers (3)

Peter Seliger
Peter Seliger

Reputation: 13366

The following approach uses a combination of two regular expressions, one for retrieving/matching the raw file data ...

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

... and a second one in order to help processing the final data structure ...

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

Both reg-expressions use Capturing groups the second one does it via named groups in order to create the final data structure just by Destructuring assignments where the latter is used to only assign fields like width and height in case they actually could be retrieved.

There are 3 example loggings, stepwise progressing the data handling in order to give an idea of all involved data processing steps ...

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; }

Upvotes: 1

anubhava
anubhava

Reputation: 784968

You may use this regex to build your output:

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

Updated RegEx Demo

Code and 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);

Upvotes: 3

Peter Pointer
Peter Pointer

Reputation: 4162

The | needs to be escaped

You have to escape the | character that precedes "width":

Corrected regex:

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

You do not have to escape the ! at the beginning according to regex101. Feel free to add \! again if your regex dialect needs it.

Optional width

In case only height is given we should check for given width or height:

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

Upvotes: 1

Related Questions