Reputation: 3806
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
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
Reputation: 784968
You may use this regex to build your output:
/!([^|!]*(?:jpe?g|png|gif|pdf|xlx))(?:\|width=(\d*\.?\d+%?)(?:,height=(\d*\.?\d+%?))?)?!/g
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
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