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}, ....]
Esto es lo que intenté, pero la expresión regular no está dando la coincidencia correcta y su grupo coincidente: -
Puede usar esta expresión regular para construir su salida:
/!([^|!]*(?:jpe?g|png|gif|pdf|xlx))(?:\|width=(\d*\.?\d+%?)(?:,height=(\d*\.?\d+%?))?)?!/g
Demostración RegEx actualizada
Código y demostración:
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);
el | necesita ser escapado
Tienes que escapar de la |
carácter que precede a "ancho":
Regex corregido:
!(.*(jpg|png|gif|pdf|xlx))\|(width=.+)!
¡No tienes que escapar del !
al principio de acuerdo con regex101. Siéntase libre de agregar \!
de nuevo si su dialecto de expresiones regulares lo necesita.
Ancho opcional
En caso de que solo se proporcione la altura, debemos verificar el ancho o la altura dados:
!(.*(jpg|png|gif|pdf|xlx))(\|((width|height)=.+)!)?
El siguiente enfoque utiliza una combinación de dos expresiones regulares, una para recuperar/ coincidir con los datos del archivo sin procesar ...
/[!"]+([^!"]+)[!"]/gm
... y una segunda para ayudar a procesar la estructura de datos final ...
/^(?<fileName>[^.]+\.(?:jpg|png|gif|pdf|xlx))(?:\|(?:width=(?<width>.*?))?,?(?:height=(?<height>.*?))?)?$/
Ambas expresiones regulares usan grupos de captura, la segunda lo hace a través de grupos con nombre para crear la estructura de datos final simplemente desestructurando asignaciones donde la última se usa solo para asignar campos como width
y height
en caso de que realmente puedan recuperarse.
Hay 3 registros de ejemplo, progresando paso a paso en el manejo de datos para dar una idea de todos los pasos involucrados en el procesamiento de datos...
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; }