splitSentences: Troceado de markdown en frases
Firma
export function splitSentences(text: string): string[]
Propósito
Trocea texto markdown en “frases” (unidades atómicas) para que trimChunksBySentence pueda embeberlas y puntuar por similaridad. Es conservador: respeta estructuras que no deben partirse para mantener integridad semántica.
Comportamiento
Estructuras preservadas (no se trocean)
- Code blocks fenced (
```/~~~): Un bloque entero = una unidad. Se trocean en el nivel de bloque, nunca dentro. - Filas de tabla (
| ... |): Cada fila = una unidad. - Bullets / Numeradas (
-,*,+,N.): Cada ítem = una unidad. - Blockquotes (
>): Cada línea = una unidad. - Headings (
#,##, etc.): Cada línea = una unidad.
Partición en prosa
- Parte por
./!/?seguidos de espacio y mayúscula o apertura (",',(,¿,¡). - Protege antes de partir:
- Abreviaturas:
etc.,Sr.,Dra.,p.ej,v.g,cf.,vs.,approx.,min,max,seg,ms,kb,mb,gb,tb(lista ES/EN). - Decimales:
3.14,1.5. - Versiones:
v1.2.3. - IPs:
192.168.1.1.
- Abreviaturas:
- Sustitución temporal: punto en abreviatura → placeholder
Z9DOTZ9, partición, luego restauración.
Output
Array de strings, cada uno una frase/unidad. Sin vacías (filtradas).
Ejemplos
const ex1 = splitSentences("Hola. ¿Cómo estás?");
// ["Hola.", "¿Cómo estás?"]
const ex2 = splitSentences("La v.1.2.3 fue publicada.");
// ["La v.1.2.3 fue publicada."] // no parte en los puntos de versión
const ex3 = `
function foo() {
console.log("hola");
}
Explicación. Otro párrafo.
`;
// [
// "function foo() {\n console.log(\"hola\");\n}",
// "Explicación.",
// "Otro párrafo."
// ]
const ex4 = splitSentences("- Item 1\n- Item 2");
// ["- Item 1", "- Item 2"]
Detalles de implementación
Paso 1: Extraer code blocks
Usa regex /(\“[\s\S]?```|~~~[\s\S]?~~~)/gpara capturar bloques enteros y reemplazarlos por placeholdersZ9CODE${i}Z9`.
Paso 2: Separar por párrafos
Split por \n\s*\n (líneas en blanco). Cada párrafo se procesa por separado.
Paso 3: Detectar estructuras (por línea)
Si el párrafo contiene líneas que matchean /^\s*(?:[-*+]\s|\d+[.)]\s|\||>|#{1,6}\s)/, trátalas como estructurales: emite cada línea como unidad.
Paso 4: Prosa normal
- Proteger puntos de abreviaturas / decimales / IPs.
- Split por
./!/?seguidos de espacio + mayúscula/apertura. - Restaurar placeholders.
- Trimear cada unidad.
Paso 5: Restaurar code blocks
Reemplazar placeholders Z9CODE(\d+)Z9 por el bloque original.
Fuentes de datos
- Entrada:
contentde unChunkMatch(texto markdown procedente del índice D1). - Salida: Array de strings, cada uno a embeberase.
- Parámetros: Ninguno (determinista).
Notas
- Performance: O(n) en longitud del texto. Dos pasadas de regex + split.
- Seguridad: Usa placeholders improbables (
Z9DOTZ9,Z9CODE${i}Z9) que no colisionan con prosa normal. - Internacionalización: Soporta abreviaturas ES/EN comunes. Lista amplible en
SENT_ABBREV. - Casos edge: Si un párrafo es 100% un code block placeholder, detectado y emitido como unidad sin troceado.
Véase también
- [[feature—biblioteca—arcrift-sentence-trimming]]
- [[entity—functions—service—trim-chunks-by-sentence]]
- [[entity—functions—service—retrieve]]