forgehub. A small, independent toolbox

Regex Tester

Why does my regex miss lines or stop at a line break?

Enable m when ^ and $ should identify individual lines. Enable s when a dot must consume line breaks. Keep g enabled to inspect every non-overlapping match. In Regex Tester, compare these flags on a small sample, then check the highlighted boundaries: a greedy .* can combine several blocks even when the flags are correct.

Open Regex Tester

Separate line boundaries from text spanning lines

A log can contain several lines without needing every available flag. First decide what one match should contain: a single error line, or a block whose opening and closing markers sit on different lines. Those jobs require different changes to the expression.

In Regex Tester, m is Multiline: it changes where ^ and $ can match. The s control is Dot all: it allows a dot to match line breaks. Selecting m does not give a dot that ability. Enter the pattern alone in Expression and choose flags with the checkboxes. Leave i and u off for the examples below so each change is easy to inspect.

Find complete error lines with Multiline

Paste three lines into Test text: INFO: ready on the first, ERROR: disk full on the second, and ERROR: retry failed on the third. Use actual line breaks between them. Enter ^ERROR: .+$ in Expression and leave only g enabled. This sample produces no matches because the start anchor refers to the start of the whole text, which begins with INFO.

Now enable m while keeping g selected. The two ERROR lines become separate matches. The anchors apply to each line, while the dot consumes the message on that line. You do not need s for this task. With these exact lines separated by single line-feed characters, the offsets are 12 to 28 and 29 to 48; the end position is exclusive.

Keep g on when you want both errors. Switching it off returns only the first match, even with m enabled. A count of one can therefore reflect the Global setting rather than a failure to recognize the next error line.

Cross a line break with Dot all

For a block example, replace Test text with six lines: BEGIN, first, END, BEGIN, second, END. Enter BEGIN.*?END and select g and m, leaving s off. There are no matches: the dot cannot consume the line break immediately after BEGIN. Moving anchor behavior with m cannot help this pattern, which has no anchors.

Turn m off and s on, keeping g selected. The expression now finds two blocks: BEGIN through the first END, followed by BEGIN through the second END. Each highlight spans three lines. This makes a useful diagnostic: when the missing part of a match is a line break consumed by a dot, investigate s rather than enabling m automatically.

Check whether a greedy match joins separate blocks

Keep the same six-line sample and g plus s. Change BEGIN.*?END to BEGIN.*END by removing the question mark. The result becomes one match covering both blocks. The greedy .* can continue through the first END and stop at the later END. Global cannot split text that the first match already consumed.

Restore the question mark for this simple marker example. The lazy .*? stops at the earliest END that lets the expression succeed, restoring two matches. Inspect the highlight boundaries as well as the count. This example assumes plain, separate markers; it does not establish a parser for nested blocks or content that itself contains END.

Bring the corrected pattern back to your real sample

Add a few representative lines from your actual text, including a case that should remain unmatched. Change one flag or pattern feature at a time. Edits clear previous results and schedule another evaluation; wait for the completed status or select Run / retry before judging the change.

Check for the partial-highlights notice if the text contains many matches: the app shows at most 1,000. A timeout reports an incomplete result, so shorten the sample or simplify the pattern before drawing conclusions. Save the useful expression and selected flags in your own notes; the app keeps no saved session.

AI-assisted ForgeHub editorial. App capabilities were checked against its implementation; this guide is not an independent review.

Frequently asked questions

Do I need m whenever my test text has several lines?

No. Use m when ^ and $ should recognize individual line boundaries. An unanchored expression can find text on a later line without m. In the block example, s supplies the needed change because a dot must consume line breaks.

Can I select Multiline and Dot all together?

Yes. The app exposes separate m and s controls and passes selected flags to JavaScript RegExp. Combine them when you need both line anchors and dots that cross line breaks; neither control replaces the other.

Why does Global still show one match for two blocks?

Global finds non-overlapping matches. With BEGIN.*END and s enabled, one greedy match can consume both blocks. In the simple example, BEGIN.*?END gives two separate matches because it stops at the earlier closing marker.