URL: https://gist.github.com/peterbe/a210437cd282ef0963749520f6b09a1c

I need this function to relate to open-editor which is a Node program that can open your $EDITOR from Node and jump to a specific file, to a specific line, to a specific column.

Here's the code:


function* findMatchesInText(needle, haystack, { inQuotes = false } = {}) {
  const escaped = needle.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
  let rex;
  if (inQuotes) {
    rex = new RegExp(`['"](${escaped})['"]`, "g");
  } else {
    rex = new RegExp(`(${escaped})`, "g");
  }
  for (const match of haystack.matchAll(rex)) {
    const left = haystack.slice(0, match.index);
    const line = (left.match(/\n/g) || []).length + 1;
    const lastIndexOf = left.lastIndexOf("\n") + 1;
    const column = match.index - lastIndexOf + 1;
    yield { line, column };
  }
}

And you use it like this:


const text = ` bravo
Abra
cadabra

bravo
`;

console.log(Array.from(findMatchesInText("bra", text)));

Which prints:


[
  { line: 1, column: 2 },
  { line: 2, column: 2 },
  { line: 3, column: 5 },
  { line: 5, column: 1 }
]

The inQuotes option is because a lot of times this function is going to be used for finding the href value in unstructured documents that contain HTML <a> tags.

Comments

Your email will never ever be published.

Previous:
hashin 0.15.0 now copes nicely with under_scores June 15, 2020 Python
Next:
Test if two URLs are "equal" in JavaScript July 2, 2020 JavaScript
Related by category:
You don't need a context or state manager for TanStack Query in scattered React components January 2, 2026 JavaScript
Always run biome migrate after upgrading biome August 16, 2025 JavaScript, Node
Video to Screenshots app June 21, 2025 JavaScript
Starting a side project: PissueTracker March 16, 2025 JavaScript
Related by keyword:
In JavaScript (Node) which is fastest, generator function or a big array function? March 5, 2021 Node, JavaScript