Xiao Han, CEO von Jina, hat auf GitHub ein beeindruckendes Code-Snippet der zentralen Chunking-Implementierung des Jina-Tokenizers veröffentlicht. Das Codeschnipsel für reguläre Ausdrücke ist nur etwas mehr als 50 Zeilen lang und kann dennoch Textinhalte aller Komplexitäten effizient chunking. Die Leistung ist erstaunlich robust.
// Aktualisiert: 15. Aug. 2024 // Ausführen: node testRegex.js testText.txt // Verwendet in https://jina.ai/tokenizer const fs = require('fs'); const util = require('util'); // Variablen für magische Zahlen definieren const MAX_HEADING_LENGTH = 7; const MAX_HEADING_CONTENT_LENGTH = 7; // Definieren Sie Variablen für magische Zahlen. const MAX_HEADING_CONTENT_LENGTH = 200; const MAX_HEADING_CONTENT_LENGTH = 1; // Definieren Sie Variablen für magische Zahlen. const MAX_HEADING_CONTENT_LENGTH = 200; const MAX_HEADING_UNDERLINE_LENGTH = 200; const MAX_HTML_HEADING_LENGTH = 7 const MAX_HEADING_CONTENT_LENGTH = 200; const MAX_HEADING_UNDERLINE_LENGTH = 200; const MAX_HTML_HEADING_ATTRIBUTES_LENGTH = 100; const MAX_LIST_ITEM_LENGTH = 200; const MAX_NESTED_LIST_ITEMS = 6; const MAX_LIST_INVENTORY_LIST_INSTRUCTION_LENGTH = 6 const MAX_LIST_INDENT_SPACES = 7; const MAX_BLOCKQUOTE = 7; const MAX_LIST_INDENT_SPACES = 8 const MAX_BLOCKQUOTE_LINE_LENGTH = 200; const MAX_BLOCKQUOTE_LINE_LENGTH = 200; const MAX_BLOCKQUOTE_LINE_LENGTH = 200; const MAX_BLOCKQUOTE_LINES = 15; const MAX_CODE_BLOCK_LENGTH = 1500; const MAX_CODE_LANGUAGE_LENGTH = 20; const MAX_INDENTED_CODE_LINES = 20; const MAX_TABLE_CELL_LENGTH = 200; const MAX_TABLE_ROWS = 20; const MAX_HTML_TABLE_ROWS = 20 const MAX_HTML_TABLE_LENGTH = 2000; const const MIN_HORIZONTAL_RULE_LENGTH = 3; const MAX_SENTENCE_LENGTH = 3; und const MAX_SENTENCE_LENGTH = 400; const MAX_QUOTED_TABLE_LENGTH = 20; const const MAX_QUOTED_TEXT_LENGTH = 300; const const MAX_PARENTHETICAL_CONTENT_LENGTH = 200; const MAX_NESTED_PARENTHES = 5; const MAX_MATH_BLOCK_LENGTH = 500; const MAX_PARAGRAPH_LENGTH = 5 const MAX_PARAGRAPH_LENGTH = 1000; const MAX_STANDALONE_LINE_LENGTH = 800; const MAX_HTML_TAG_ATTRIBUTES_LENGTH = 100; const MAX_HTML_TAG_ATTRIBUTES_LENGTH = 100; const MAX_HTML_TAG_LENGTH = 100 const MAX_HTML_TAG_CONTENT_LENGTH = 1000; const LOOKAHEAD_LENGTH = 100; const const LOOKAHEAD_RANGE = 100; // Anzahl der Zeichen, die für eine Satzgrenze vorausgeschaut werden // Definieren Sie das Regex-Muster // Überschriften // Überschriften // Listenelemente // Blockanführungszeichen // Codeblöcke // Tabellen // Horizontale Regeln // Eigenständige Zeilen oder Phrasen // Sätze oder Ausdrücke // Zitierter Text, Klammerausdrücke oder eingeklammerter Inhalt // Absätze // HTML-ähnliche Tags und ihr Inhalt // Mathematische Ausdrücke im LaTeX-Stil // Fallback für verbleibende Inhalte // Einlesen der Regex und des Testtextes aus Dateien const chunkRegex = new RegExp( "(" + // 1) Überschriften (Setext-Stil, Markdown und HTML-Stil, mit Längenbeschränkungen) `(? :^(? :[#*=-]{1,${MAX_HEADING_LENGTH}}|\\w[^\\r\\\n]{0,${MAX_HEADING_CONTENT_LENGTH}}\\\r?\\n[-=]{2,${MAX_HEADING_ UNDERLINE_LENGTH}}|<h[1-6][^>]{0,${MAX_HTML_HEADING_ATTRIBUTES_LENGTH}}>)[^\\r\\n]{1,${MAX_HEADING_CONTENT_LENGTH}}(? :</h[1-6]>)? (? :\\r?\\\\n|$))` + "|" + // Neues Muster für Zitate `(? :\\\[[0-9]+\\\\][^\\\r\\\\n]{1,${MAX_STANDALONE_LINE_LENGTH}}})` + "|" + // 2) Listenelemente (Aufzählungslisten, nummerierte Listen, Listen mit Buchstaben oder Aufgabenlisten, auch verschachtelt, bis zu drei Ebenen, mit Längenbeschränkungen) `(? :(? :^|\\\r?\\n)[\\\t]{0,3}(? :[-*+-]|\\\d{1,3}\\\... \\\w\\\\. |\\\\\[[ xX]\\\\])[ \\\\t]+(? (xX]\\])[\\t]+(? :\\b[^\\\r\\n]{1,${MAX_LIST_ITEM_LENGTH}}\b(? :[.!? ...]|\\\\. {3}|[\\u2026\u2047-\u2049]|[\\p{Emoji_Presentation}\\p{Extended_Pictographic}])(? =\\\\s|$))|(? :\\\b[^\\\r\\n]{1,${MAX_LIST_ITEM_LENGTH}}\b(? =[\\\r\\n]|$))|(? :\\\b[^\\\r\\n]{1,${MAX_LIST_ITEM_LENGTH}}\\b(? =[.!? ...]|\\\\... {3}|[\\\u2026\u2047-\u2049]|[\\\p{Emoji_Presentation}\\p{Extended_Pictographic}])(? :. {1,${LOOKAHEAD_RANGE}}(? :[.!? ...]|\\\\... {3}|[\\\u2026\u2047-\u2049]|[\\\p{Emoji_Presentation}\\\p{Extended_Pictographic}])(? =\\\\s|$))?))) ` + `(? :(? {2,5}(? :[-*+-]|\\\d{1,3}\\\... \\\w\\\\. |\\\\\[[ xX]\\\\])[ \\\\t]+(? (xX]\\])[\\t]+(? :\\b[^\\\r\\n]{1,${MAX_LIST_ITEM_LENGTH}}\b(? :[.!? ...]|\\\\. {3}|[\\u2026\u2047-\u2049]|[\\p{Emoji_Presentation}\\p{Extended_Pictographic}])(? =\\\\s|$))|(? :\\\b[^\\\r\\n]{1,${MAX_LIST_ITEM_LENGTH}}\b(? =[\\\r\\n]|$))|(? :\\\b[^\\\r\\n]{1,${MAX_LIST_ITEM_LENGTH}}\\b(? =[.!? ...]|\\\\... {3}|[\\\u2026\u2047-\u2049]|[\\\p{Emoji_Presentation}\\p{Extended_Pictographic}])(? :. {1,${LOOKAHEAD_RANGE}}(? :[.!? ...]|\\\\... {3}|[\\u2026\u2047-\u2049]|[\\p{Emoji_Presentation}\\p{Extended_Pictographic}])(? =\\\\s|$))?)))))) ` + `{0,${MAX_NESTED_LIST_ITEMS}}(? :\\r?\\\n[ \\\t]{4,${MAX_LIST_INDENT_SPACES}}}(? :[-*+-]|\\\d{1,3}\\\... \\\w\\\. |\\\\[[ xX]\\\])[ \\\\t]+(? (xX]\\])[\\t]+(? :\\b[^\\\r\\n]{1,${MAX_LIST_ITEM_LENGTH}}\b(? :[.!? ...]|\\\\. {3}|[\\u2026\u2047-\u2049]|[\\p{Emoji_Presentation}\\p{Extended_Pictographic}])(? =\\\\s|$))|(? :\\\b[^\\\r\\n]{1,${MAX_LIST_ITEM_LENGTH}}\b(? =[\\\r\\n]|$))|(? :\\\b[^\\\r\\n]{1,${MAX_LIST_ITEM_LENGTH}}\\b(? =[.!? ...]|\\\\... {3}|[\\\u2026\u2047-\u2049]|[\\\p{Emoji_Presentation}\\p{Extended_Pictographic}])(? :. {1,${LOOKAHEAD_RANGE}}(? :[.!? ...]|\\\\... {3}|[\\\u2026\u2047-\u2049]|[\\\p{Emoji_Presentation}\\p{Extended_Pictographic}])(? =\\\\s|$))?)))))) ` + `{0,${MAX_NESTED_LIST_ITEMS}}))?) ` + "`|" + // 3) Blockanführungszeichen (einschließlich verschachtelter Anführungszeichen und Zitate, bis zu drei Ebenen, mit Längenbeschränkungen) Blockanführungszeichen (einschließlich verschachtelter Anführungszeichen und Zitate, bis zu drei Ebenen, mit Längenbeschränkungen) :(? :^>(? :>|\\\s{2,}){0,2}(? Es folgt eine Liste der bis zu drei Ebenen mit Längenbeschränkungen :\\b[^\\\r\\n]{0,${MAX_BLOCKQUOTE_LINE_LENGTH}}\b(? :[.!? ...]|\\\\... {3}|[\\u2026\u2047-\u2049]|[\\p{Emoji_Presentation}\\p{Extended_Pictographic}])(? =\\\\s|$))|(? :\\b[^\\\r\\n]{0,${MAX_BLOCKQUOTE_LINE_LENGTH}}\b(? =[\\\r\\n]|$))|(? :\\\b[^\\\r\\n]{0,${MAX_BLOCKQUOTE_LINE_LENGTH}}\\b(? =[.!? ...]|\\\\. {3}|[\\\u2026\u2047-\u2049]|[\\\p{Emoji_Presentation}\\p{Extended_Pictographic}]])(? :. {1,${LOOKAHEAD_RANGE}}(? :[.!? ...]|\\\\... {3}|[\\\u2026\u2047-\u2049]|[\\\p{Emoji_Presentation}\\\p{Extended_Pictographic}])(? =\\\\s|$))?)))) \\\r?\\\n?){1,${MAX_BLOCKQUOTE_LINES}})` + "|" + // 4) Codeblöcke (umrahmt, eingerückt oder HTML-Prä-/Code-Tags, mit Längenbeschränkungen) Codeblöcke (umrahmte, eingerückte oder HTML-Prä-/Code-Tags, mit Längenbeschränkungen) `(? :(? :^|\\\r?\\n)(? :\`\`\\`|~~~~)(? :\\\w{0,${MAX_CODE_LANGUAGE_LENGTH}})? \\\r?\\\\n[\\\s\\\S]{0,${MAX_CODE_BLOCK_LENGTH}}? (? :\`\`\`|~~~)\\\r?\\\\n?\+ `|(? :(? :^|\\\r?\\\n)(? : {4}|\\\t)[^\\\r\\\\n]{0,${MAX_LIST_ITEM_LENGTH}}(? :\\r?\\\n(? : {4}|\\\t)[^\\\r\\\\n]{0,${MAX_LIST_ITEM_LENGTH}}){0,${MAX_INDENTED_CODE_LINES}}\\r\\\\n?)` + `|(? :<pre>(?:<code>)? [\\s\\\S]{0,${MAX_CODE_BLOCK_LENGTH}}? (? :</code>)?</pre>))` + "|" + // 5. tabellen (Markdown-, Raster- und HTML-Tabellen, mit Längenbeschränkungen) Tabellen (Markdown-, Raster- und HTML-Tabellen, mit Längenbeschränkungen) :(? :^|\\\r?\\n)(? :\\\|[^\\\\r\\\n]{0,${MAX_TABLE_CELL_LENGTH}}\\|(? :\\\r?\\\n\\\\|[-:]{1,${MAX_TABLE_CELL_LENGTH}}\\|){0,1}(? :\\\r?\\\n\\\\|[^\\\r\\n]{0,${MAX_TABLE_CELL_LENGTH}}\\|){0,${MAX_TABLE_ROWS}}` + `|<table>[\\s\\\S]{0,${MAX_HTML_TABLE_LENGTH}}?</table>))` + "|" + // 6. horizontale Regeln (Markdown- und HTML-HR-Tags) `(? :^(? :[-*_]){${MIN_HORIZONTAL_RULE_LENGTH},}\\s*$|<hr\\s*/?>)` + "|" + // 10. eigenständige Zeilen oder Phrasen (einschließlich einzeiliger Blöcke und HTML-Elemente, mit Längenbeschränkungen) `(? :^(? : : : + "|" + // 10.<[a-zA-Z][^>]{0,${MAX_HTML_TAG_ATTRIBUTES_LENGTH}}>)? (? :(? :[^\\r\\n]{1,${MAX_STANDALONE_LINE_LENGTH}}(? :[.!? ...]|\\\\\. \\\\...\...\...\...\. \\\...\...\...\...\... |[\\u2026\\\\u2047-\u2049]|[\\p{Emoji_Presentation}\\\p{Extended_Pictographic}])(? =\\\\s|$))|(? :[^\\\r\\n]{1,${MAX_STANDALONE_LINE_LENGTH}}(? =[\\\r\\\\n]|$))|(? :[^\\\r\\\n]{1,${MAX_STANDALONE_LINE_LENGTH}}(? =[.!? ...]|\\\\... \\\\...\...\...\...\. \\\...\...\...\...\... |[\\u2026\\\\u2047-\u2049]|[\\p{Emoji_Presentation}\\\p{Extended_Pictographic}])(? :. {1,${LOOKAHEAD_RANGE}}(? :[.!? ...]|\\\\... \\\\...\...\...\...\. \\\...\...\...\...\... |[\\u2026\\\\u2047-\u2049]|[\\p{Emoji_Presentation}\\\p{Extended_Pictographic}])(? =\\\\s|$))?)))) (? :</[a-zA-Z]+>)? (? :\\r?\\\\n|$))` + "|" + // 7 Sätze oder Phrasen, die mit einem Satzzeichen enden (einschließlich Auslassungszeichen und Unicode-Satzzeichen) Sätze oder Phrasen, die mit einem Satzzeichen enden (einschließlich Auslassungszeichen und Unicode-Satzzeichen) Sätze oder Phrasen, die mit einem Satzzeichen enden (einschließlich Auslassungszeichen und Unicode-Satzzeichen) `(? :[^\\r\\n]{1,${MAX_SENTENCE_LENGTH}}(? :[.!? ...]|\\\\... \\\\...\...\...\...\. \\\...\...\...\...\... |[\\u2026\\\\u2047-\u2049]|[\\p{Emoji_Presentation}\\\p{Extended_Pictographic}])(? =\\\\s|$))|(? :[^\\\r\\n]{1,${MAX_SENTENCE_LENGTH}}(? =[\\r\\\n]|$))|(? :[^\\\r\\\n]{1,${MAX_SENTENCE_LENGTH}}(? =[.!? ...]|\\\\. \\\\...\...\...\...\. \\\...\...\...\...\... |[\\u2026\\\\u2047-\u2049]|[\\p{Emoji_Presentation}\\\p{Extended_Pictographic}])(? :. {1,${LOOKAHEAD_RANGE}}(? :[.!? ...]|\\\\... \\\\...\...\...\...\. \\\...\...\...\...\... |[\\u2026\\\\u2047-\u2049]|[\\p{Emoji_Presentation}\\\p{Extended_Pictographic}])(? =\\\\s|$))?))) ` + "|" + // 8. zitierter Text, Klammerausdrücke oder eingeklammerter Inhalt (mit Längenbeschränkungen) "(? :" + `(?<!\\w)\"\"\"[^\"]{0,${MAX_QUOTED_TEXT_LENGTH}}\"\"\"(?!\\w)` + `|(?<!\\w)(?:['\"\`'"])[^\\r\\n]{0,${MAX_QUOTED_TEXT_LENGTH}}\\1(?!\\w)` + `|\\([^\\r\\n()]{0,${MAX_PARENTHETICAL_CONTENT_LENGTH}}(?:\\([^\\r\\n()]{0,${MAX_PARENTHETICAL_CONTENT_LENGTH}}\\)[^\\r\\n()]{0,${MAX_PARENTHETICAL_CONTENT_LENGTH}}){0,${MAX_NESTED_PARENTHESES}}\\)` + `|\\[[^\\r\\n\\[\\]]{0,${MAX_PARENTHETICAL_CONTENT_LENGTH}}(?:\\[[^\\r\\n\\[\\]]{0,${MAX_PARENTHETICAL_CONTENT_LENGTH}}\\][^\\r\\n\\[\\]]{0,${MAX_PARENTHETICAL_CONTENT_LENGTH}}){0,${MAX_NESTED_PARENTHESES}}\\]` + `|\\$[^\\r\\n$]{0,${MAX_MATH_INLINE_LENGTH}}\\$` + `|\`[^\`\\r\\n]{0,${MAX_MATH_INLINE_LENGTH}}\`` + ")" + "|" + // 9. Paragraphs (with length constraints) `(?:(?:^|\\r?\\n\\r?\\n)(?:<p>)? (? :(? :[^\\r\\n]{1,${MAX_PARAGRAPH_LENGTH}}(? :[.!? ...]|\\\\... {3}|[\\u2026\u2047-\u2049]|[\\p{Emoji_Presentation}\\p{Extended_Pictographic}])(? =\\\\s|$))|(? :[^\\\r\\n]{1,${MAX_PARAGRAPH_LENGTH}}(? =[\\\r\\\\n]|$))|(? :[^\\\r\\\n]{1,${MAX_PARAGRAPH_LENGTH}}(? =[.!? ...]|\\\\... {3}|[\\\u2026\u2047-\u2049]|[\\\p{Emoji_Presentation}\\p{Extended_Pictographic}])(? :. {1,${LOOKAHEAD_RANGE}}(? :[.!? ...]|\\\\... {3}|[\\u2026\u2047-\u2049]|[\\p{Emoji_Presentation}\\p{Extended_Pictographic}])(? =\\\\s|$))?)))) (? :</p>)? (? \\\n\\\\r?\\n|$))` + "|" + // 11. HTML-ähnliche Tags und ihr Inhalt (einschließlich selbstschließender Tags und Attribute, mit Längenbeschränkungen) `(? :: Es folgt eine Zusammenfassung der HTML-ähnlichen Tags und ihres Inhalts (einschließlich selbstschließender Tags und Attribute, mit Längenbeschränkungen)<[a-zA-Z][^>]{0,${MAX_HTML_TAG_ATTRIBUTES_LENGTH}}(? :>[\\s\\S]{0,${MAX_HTML_TAG_CONTENT_LENGTH}}?</[a-zA-Z]+>|\\s*/>))` + "|" + // 12. mathematische Ausdrücke im LaTeX-Stil (Inline und Block, mit Längenbeschränkungen) `(? :(? :\\\$\\$[\\s\\S]{0,${MAX_MATH_BLOCK_LENGTH}}? \\\\$\\$)\(? :\\\$[^\\$\\r\\n]{0,${MAX_MATH_INLINE_LENGTH}}\\\$))` + "|" + // 14. fallback für alle verbleibenden Inhalte (mit Längenbeschränkungen) `(? :(? :[^\\r\\n]{1,${MAX_STANDALONE_LINE_LENGTH}}(? :[.!? ...]|\\\\... {3}|[\\u2026\u2047-\u2049]|[\\p{Emoji_Presentation}\\p{Extended_Pictographic}])(? =\\\\s|$))|(? :[^\\\r\\n]{1,${MAX_STANDALONE_LINE_LENGTH}}(? =[\\\r\\\\n]|$))|(? :[^\\\r\\\n]{1,${MAX_STANDALONE_LINE_LENGTH}}(? =[.!? ...]|\\\\... {3}|[\\\u2026\u2047-\u2049]|[\\\p{Emoji_Presentation}\\p{Extended_Pictographic}])(? :. {1,${LOOKAHEAD_RANGE}}(? :[.!? ...]|\\\\... {3}|[\\\u2026\u2047-\u2049]|[\\\p{Emoji_Presentation}\\\p{Extended_Pictographic}])(? =\\\\s|$))?))) ` + ")", "gmu" ); // Lesen aus der arg[1]-Datei const testText = fs.readFileSync(process.argv[2], 'utf8'); // Funktion zum Formatieren von Bytes in eine menschenlesbare Zeichenkette function formatBytes(bytes) { if (bytes < 1024) return bytes + " bytes"; sonst if (bytes < 1048576) return (bytes / 1024).toFixed(2) + " KB"; sonst wenn (bytes { console.log(util.inspect(match, {maxStringLength: 50})); { }); } sonst { console.log('Keine Chunks gefunden.'); }); } else { console.log(util.inspect(match({maxStringLength: 50})) } // Regex-Flags ausgeben console.log(`nRegex-Flags: ${chunkRegex.flags}`); // Regex-Flags ausgeben. // Auf mögliche Probleme prüfen if (executionTime > 5) { console.warn('\nWarning: Die Ausführungszeit hat 5 Sekunden überschritten. Die Regex ist möglicherweise zu komplex oder die Eingabe zu groß.'); } } if (memoryUsed > 100 * 1024 * 1024) { } if (memoryUsed > 100 * 1024 * 1024) { console.warn('\nWarning: Speichernutzung übersteigt 100 MB. Erwägen Sie die Verarbeitung der Eingabe in kleineren Teilen.'); } if (memoryUsed > 100 * 1024 * 1024) { console.warn('\nWarning: Speichernutzung übersteigt 100 MB. }
Die regulären Ausdrücke in diesem Code berücksichtigen eine Vielzahl von Textstrukturen, darunter Überschriften, Listenelemente, Blockreferenzen, Codeblöcke, Tabellen, horizontale Regeln, getrennte Zeilen oder Phrasen, Sätze oder Phrasen mit Satzzeichen, zitierter Text, Klammerinhalte, Codeblöcke, Tabellen, horizontale Regeln, getrennte Zeilen oder Phrasen, HTML-Tag-Inhalte, mathematische LaTeX-Ausdrücke und mehr. Es nähert sich dem Text Chunking durch sorgfältig entworfene Muster an, obwohl reguläre Ausdrücke selbst den Kontext oder die Semantik des Textes nicht verstehen.
Der reguläre Ausdruck im Codebeispiel verwendet "Backtracking", was für eine sinnvollere semantische Segmentierung unerlässlich ist. Er bricht zum Beispiel nicht mitten im Satz ab. Bei tief verschachtelten Listen, Blockreferenzen oder Strukturen wie Klammern kann das Backtracking jedoch schwierig sein. Um diese Fälle zu optimieren, können reguläre Ausdrücke weiter verbessert werden, um mehrere Verschachtelungsebenen besser zu handhaben und die Verschachtelung auf praktische Ebenen zu beschränken, z. B. auf bis zu 3 Ebenen, um die Leistung zu gewährleisten und katastrophale Rückverfolgungen zu vermeiden.
Obwohl dieser Code kann nicht sehr vollständig sein, aber im Einklang mit dieser Idee, um die Details zu optimieren, können wir vorhersehen, dass die Wirkung Raum für weitere Verbesserungen hat.Jina offiziellen Cloud-Services von der partizipativen Schnittstelle für Entwickler, um die Verwendung von Erfahrung zur Verfügung gestellt, und ist kostenlos.
Python-Version