Estoy tratando de dividir una cadena multilínea usando una expresión regular.
const regexCommitSha = RegExp(/([0-9a-f]{7})\s/m) const result = commits.split(regexCommitSha) console.log(result) Esta es mi cadena multilínea ( commits ):
1234567 fix: simple bug fix apps/backend/src/lib/file.ts 1234567 fix: second bug fix apps/backend/src/lib/file.ts apps/frontend/src/lib/file.ts 1234567 feat: new feature apps/frontend/src/lib/file.ts 1234567 feat: second feature apps/frontend/src/lib/file.tsY este es mi resultado:
[ '', '1234567', 'fix: simple bug fix\napps/backend/src/lib/file.ts\n', '1234567', 'fix: second bug fix\n' + 'apps/backend/src/lib/file.ts\n' + 'apps/frontend/src/lib/file.ts\n', '1234567', 'feat: new feature\napps/frontend/src/lib/file.ts\n', '1234567', 'feat: second feature\napps/frontend/src/lib/file.ts' ] ¿Por qué tengo la cadena vacía como primer elemento y por qué tengo elementos '1234567' en mi matriz de resultados? Como este es mi divisor, pensé que esto no existe en el resultado.
Yo esperaría
[ 'fix: simple bug fix\napps/backend/src/lib/file.ts\n', 'fix: second bug fix\n' + 'apps/backend/src/lib/file.ts\n' + 'apps/frontend/src/lib/file.ts\n', 'feat: new feature\napps/frontend/src/lib/file.ts\n', 'feat: second feature\napps/frontend/src/lib/file.ts' ]¿Qué estoy haciendo mal?
Puede reemplazar la expresión regular con
// No grouping in the regex const regexCommitSha = RegExp(/[0-9a-f]{7}\s/m) Esto soluciona el problema por el que obtiene 1234567 s incluso después de dividir estos valores. Así es como se comporta .split con la captura de grupos (para obtener más detalles, vea esto: javascript regex split produce demasiados elementos )
En cuanto a por qué está obteniendo una cadena vacía en el conjunto de resultados, así es como funciona la división de JavaScript. Fíjate en el ejemplo,
s = "a1bbbc" s.split("a1") // ["", "bbcd"]Un grupo de captura en una expresión regular con .split incluirá el texto capturado en la matriz resultante; dado que no desea que se incluyan los números, no los coloque en un grupo de captura. (De todos modos, el grupo no está logrando nada útil). También debe excluir la cadena vacía inicial (porque la cadena vacía se encuentra entre el comienzo de la cadena y la primera división en la coincidencia), lo que debería hacerse filtrando el matriz después.
const input = `1234567 fix: simple bug fix apps/backend/src/lib/file.ts 1234567 fix: second bug fix apps/backend/src/lib/file.ts apps/frontend/src/lib/file.ts 1234567 feat: new feature apps/frontend/src/lib/file.ts 1234567 feat: second feature apps/frontend/src/lib/file.ts`; const result = input.split(/[\da-f]{7}\s/m).filter(Boolean); console.log(result) Si desea obtener una serie de cadenas que coincidan con un patrón, en mi experiencia, .match suele ser un poco más predecible y confiable; busque dígitos hacia atrás, luego haga coincidir los caracteres y las líneas que no comienzan con dígitos.
const input = `1234567 fix: simple bug fix apps/backend/src/lib/file.ts 1234567 fix: second bug fix apps/backend/src/lib/file.ts apps/frontend/src/lib/file.ts 1234567 feat: new feature apps/frontend/src/lib/file.ts 1234567 feat: second feature apps/frontend/src/lib/file.ts`; const matches = input.match(/(?<=\d{7} ).+?(?=\n\d{7}|$)/gs); console.log(matches);No tienes que hacerlo todo en una sola operación.
\n const input = ` 1234567 fix: simple bug fix apps/backend/src/lib/file.ts 1234567 fix: second bug fix apps/backend/src/lib/file.ts apps/frontend/src/lib/file.ts 1234567 feat: new feature apps/frontend/src/lib/file.ts 1234567 feat: second feature apps/frontend/src/lib/file.ts `; const lines = input .split('\n') // break into lines .map(line => line.replace(/^\d+/, '').trim()) // remove leading numbers .filter(line => line.length > 0); // remove empty strings const output = lines .reduce((groups, line) => { if (/^\w+:/.test(line)) { groups.push(line); } else { groups[groups.length-1] += '\n' + line; } return groups; }, []); console.log(output);