const regex = /\A # Begin at the beginning only! (No doing it again)
(?: # Non-capturing group consuming the string
(?| # Branch reset on two groups: p2 and p3 (p for prefix)
. # Consume a character
(?=.*+\n(?<p2>\k<p2>?+.) # Lookahead: Go to next line. Then add a character to a group
.*+\n(?<p3>\k<p3>?+.)) # Same. Will fail if the line is too short.
| # When the first brach fails:
.*+\n(?<p2>)(?<p3>) # Consume the rest of the string. Reset the groups.
)+? # As little as possible (Only one character at a time)
(?<=X)(?=.*\n\k<p2>(?<=X).*\n\k<p3>(?<=X)) # Check to see if there's a column of X's
(?=[\s\S]*(?<count>[\s\S](?(<count>)\k<count>))) # Add a character to a count group at the end.
)+ # Keep doing it until all is consumed/gm;
// Alternative syntax using RegExp constructor
// const regex = new RegExp('\\A # Begin at the beginning only! (No doing it again)
(?: # Non-capturing group consuming the string
(?| # Branch reset on two groups: p2 and p3 (p for prefix)
. # Consume a character
(?=.*+\\n(?<p2>\\k<p2>?+.) # Lookahead: Go to next line. Then add a character to a group
.*+\\n(?<p3>\\k<p3>?+.)) # Same. Will fail if the line is too short.
| # When the first brach fails:
.*+\\n(?<p2>)(?<p3>) # Consume the rest of the string. Reset the groups.
)+? # As little as possible (Only one character at a time)
(?<=X)(?=.*\\n\\k<p2>(?<=X).*\\n\\k<p3>(?<=X)) # Check to see if there\'s a column of X\'s
(?=[\\s\\S]*(?<count>[\\s\\S](?(<count>)\\k<count>))) # Add a character to a count group at the end.
)+ # Keep doing it until all is consumed', 'gm')
const str = `XX
XX
XX
X
X
X`;
// Reset `lastIndex` if this regex is defined globally
// regex.lastIndex = 0;
let m;
while ((m = regex.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
console.log(`Found match, group ${groupIndex}: ${match}`);
});
}
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for JavaScript, please visit: https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions