find_regex_position
Locate regex pattern matches in a file with precise line and column positions. Supports absolute file paths and returns detailed match data for text analysis and LSP-like functionality.
Instructions
Find the positions (line and column) of regex pattern matches in a file. Returns an array of matches with their positions. Line and column numbers are 0-indexed (first line is 0). Each match includes: match (matched text), line (starting line), column (starting column), endLine (ending line), and endColumn (ending column, exclusive). IMPORTANT: The path parameter must be an absolute path. Relative paths are not supported.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute path to the file to search in. Relative paths are not supported. | |
| regex | Yes | Regular expression pattern to search for |
Input Schema (JSON Schema)
Implementation Reference
- src/index.ts:96-118 (handler)The main handler for the 'find_regex_position' tool. Parses input arguments using the schema, validates the file path against allowed directories, calls the helper function to find regex positions, and returns the results as JSON text content.case "find_regex_position": { try { // Validate input const parsed = FindRegexPositionArgsSchema.parse(args); // Validate path for security const validatedPath = await validatePath(parsed.path, allowedDirectories); // Find regex positions const positions = await findRegexPositionsInFile(validatedPath, parsed.regex); return { content: [{ type: 'text', text: JSON.stringify(positions), }] }; } catch (error) { return { error: error instanceof Error ? error.message : String(error), }; } }
- src/index.ts:43-46 (schema)Zod schema defining the input arguments for the 'find_regex_position' tool: path (absolute file path) and regex (pattern string).const FindRegexPositionArgsSchema = z.object({ path: z.string().describe("Absolute path to the file to search in. Relative paths are not supported."), regex: z.string().describe("Regular expression pattern to search for"), });
- src/index.ts:69-77 (registration)Registration of the 'find_regex_position' tool in the listTools response, including name, detailed description, and input schema.name: "find_regex_position", description: "Find the positions (line and column) of regex pattern matches in a file. " + "Returns an array of matches with their positions. " + "Line and column numbers are 0-indexed (first line is 0). " + "Each match includes: match (matched text), line (starting line), column (starting column), " + "endLine (ending line), and endColumn (ending column, exclusive). " + "IMPORTANT: The path parameter must be an absolute path. Relative paths are not supported.", inputSchema: zodToJsonSchema(FindRegexPositionArgsSchema),
- src/utils/regex-utils.ts:29-102 (helper)Core helper function that implements the regex matching logic on content string, calculating 0-indexed start/end line and column positions for each match.export function findRegexPositionsInContent(content: string, regexStr: string): RegexMatchPosition[] { // Split content into lines for position calculation const lines = content.split("\n"); try { // Create regex with global flag to find all matches const regex = new RegExp(regexStr, "g"); const matches: RegexMatchPosition[] = []; let match: RegExpExecArray | null; // Process each match while ((match = regex.exec(content)) !== null) { const matchText = match[0]; const matchStartIndex = match.index; // Calculate line and column for start position let currentIndex = 0; let startLine = 0; let startColumn = 0; for (let i = 0; i < lines.length; i++) { const lineLength = lines[i].length + 1; // +1 for the newline character if (currentIndex + lineLength > matchStartIndex) { startLine = i; startColumn = matchStartIndex - currentIndex; break; } currentIndex += lineLength; } // Calculate line and column for end position let endLine = startLine; let endColumn = startColumn; let charsRemaining = matchText.length; while (charsRemaining > 0 && endLine < lines.length) { const lineRemainder = lines[endLine].length - endColumn + 1; // +1 for newline if (charsRemaining <= lineRemainder) { endColumn += charsRemaining; charsRemaining = 0; } else { charsRemaining -= lineRemainder; endLine++; endColumn = 0; } } // Adjust end column to be exclusive (pointing to the character after the match) if (endColumn > 0 && lines[endLine] && endColumn <= lines[endLine].length) { // No adjustment needed, end column already points to the character after the match } else { // End of line or beyond, set to 0 and increment line endColumn = 0; endLine++; } matches.push({ match: matchText, line: startLine, column: startColumn, endLine: endLine, endColumn: endColumn }); } return matches; } catch (error) { throw new Error(`Error processing regex: ${error instanceof Error ? error.message : String(error)}`); } }
- src/utils/regex-utils.ts:18-21 (helper)Helper function that reads file content asynchronously and delegates to findRegexPositionsInContent for processing.export async function findRegexPositionsInFile(filePath: string, regexStr: string): Promise<RegexMatchPosition[]> { const content = await fs.readFile(filePath, "utf-8"); return findRegexPositionsInContent(content, regexStr); }