n8n-nodes-text-splitter-chunker
Version:
n8n node to split text into chunks.
167 lines (161 loc) • 6.23 kB
text/typescript
// BY OXSR github
import {
IExecuteFunctions,
INodeExecutionData,
INodeType,
INodeTypeDescription,
} from 'n8n-workflow';
export class TextSplitterChunker implements INodeType {
description: INodeTypeDescription = {
displayName: 'Text Splitter & Chunker',
name: 'textSplitterChunker',
icon: 'fa:cut',
group: ['transform'],
version: 2,
description: 'Splits or extracts text using length, paragraph, sentence, word, or regex.',
defaults: {
name: 'Text Splitter & Chunker',
},
inputs: ['main'],
outputs: ['main'],
properties: [
{
displayName: 'Text Field',
name: 'textField',
type: 'string',
default: 'text',
description: 'Name of the field in input item that contains the text to process.',
},
{
displayName: 'Operation',
name: 'operation',
type: 'options',
options: [
{ name: 'Split', value: 'split', description: 'Divide text (default)' },
{ name: 'Extract', value: 'extract', description: 'Extract matches (regex only)' },
],
default: 'split',
},
{
displayName: 'Split Method',
name: 'splitMethod',
type: 'options',
options: [
{ name: 'Length', value: 'length' },
{ name: 'Paragraph', value: 'paragraph' },
{ name: 'Sentence', value: 'sentence' },
{ name: 'Word', value: 'word' },
{ name: 'Regex', value: 'regex' },
],
default: 'length',
displayOptions: {
show: {
operation: ['split'],
},
},
description: 'Method to split the text.',
},
{
displayName: 'Regex Pattern',
name: 'regex',
type: 'string',
default: '[aeiouáéíóúüAEIOUÁÉÍÓÚÜ]',
displayOptions: {
show: {
operation: ['extract'],
},
},
description: 'Regular expression to extract from the text.',
},
{
displayName: 'Length (characters)',
name: 'length',
type: 'number',
default: 100,
displayOptions: {
show: {
operation: ['split'],
splitMethod: ['length'],
},
},
description: 'Number of characters per chunk.',
},
{
displayName: 'Regex Pattern (for split)',
name: 'splitRegex',
type: 'string',
default: '\\n\\n+',
displayOptions: {
show: {
operation: ['split'],
splitMethod: ['regex'],
},
},
description: 'Regular expression to split the text.',
},
],
};
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const items = this.getInputData();
const returnData: INodeExecutionData[] = [];
for (let i = 0; i < items.length; i++) {
const textField = this.getNodeParameter('textField', i) as string;
const operation = this.getNodeParameter('operation', i) as string;
const text = items[i].json[textField] as string;
if (!text) {
continue;
}
if (operation === 'extract') {
const pattern = this.getNodeParameter('regex', i) as string;
const matches = text.match(new RegExp(pattern, 'gi')) || [];
for (const match of matches) {
returnData.push({
json: {
...items[i].json,
match,
},
});
}
} else { // Split
const splitMethod = this.getNodeParameter('splitMethod', i) as string;
let chunks: string[] = [];
switch (splitMethod) {
case 'length': {
const length = this.getNodeParameter('length', i) as number;
for (let pos = 0; pos < text.length; pos += length) {
chunks.push(text.slice(pos, pos + length));
}
break;
}
case 'paragraph':
chunks = text.split(/\n\s*\n/);
break;
case 'sentence':
chunks = text.match(/[^\.!\?]+[\.!\?]+/g) || [text];
break;
case 'word':
chunks = text.split(/\s+/);
break;
case 'regex': {
const pattern = this.getNodeParameter('splitRegex', i) as string;
chunks = text.split(new RegExp(pattern, 'g'));
break;
}
default:
chunks = [text];
}
for (const chunk of chunks) {
if (chunk !== '') {
returnData.push({
json: {
...items[i].json,
chunk,
},
});
}
}
}
}
return [returnData];
}
}