Remove lines matching regex
With the pattern ^DEBUG\b, a five-line log loses its 2 DEBUG lines and keeps the 3 INFO and ERROR lines untouched. You also see how many lines were removed and how many were kept. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Pattern
- ^DEBUG\b
- Text
- INFO Server started ERROR Connection lost INFO Server ready
- Removed count
- 2
- Kept count
- 3
Remove Lines Matching Regex filters multiline text by testing each individual line against a regular expression and discarding every match. It is useful when the lines you need to remove share a pattern rather than an exact value: a log level, generated comment, timestamp, identifier prefix, or structured record type. The result preserves every retained line exactly, including its original line ending, and reports how many lines were removed and kept so automated workflows can verify what changed.
Write a pattern for the complete line you want to remove
Provide the source in text and a JavaScript regular expression in pattern. Write the expression itself without slash delimiters: use <code>^DEBUG\b</code>, for example, rather than <code>/^DEBUG\b/</code>. Each line is tested separately, and a line is removed when any part of it matches.
Add <code>^</code> when the relevant text must occur at the beginning, <code>$</code> when it must occur at the end, and both anchors when the entire line must fit the rule. A pattern such as <code>^\s*#</code> removes lines whose first non-whitespace character is a hash, while <code>temporary$</code> removes lines ending with that word. Matching is case-sensitive and uses standard JavaScript regular-expression syntax.
Start with a narrow expression, inspect the counts and filtered text, then broaden it only when the result confirms that the intended lines were selected.
Understand exactly what happens to line endings and empty lines
The filter recognizes Unix line feeds, Windows carriage-return plus line-feed pairs, and standalone carriage returns. It retains the original ending attached to every line that remains, which means mixed or platform-specific input is not silently normalized. The regular expression is tested against the content of a line only; newline characters are not included in the match.
Empty lines are real lines and can be removed with a pattern such as <code>^$</code>. If the source ends with a newline, that delimiter remains attached to the preceding retained line unless that line itself is removed. Consequently, removing the last unterminated line can leave the earlier trailing delimiter intact, faithfully reflecting the bytes associated with the retained line.
An empty source is treated as one empty line, so <code>^$</code> removes it and returns zero kept lines; a nonmatching expression keeps it. No trimming, case conversion, or whitespace cleanup occurs.
Use deterministic filtering safely in logs, code, and pipelines
This capability is well suited to preprocessing data before comparison, indexing, review, or import. In logs, remove known health checks or a noisy severity prefix before sending the meaningful events to an analyst. In generated code, discard stable banner comments before comparing builds.
In structured exports, remove records whose line prefix identifies a header, trailer, or unwanted category. Because the same deterministic algorithm runs without network access, repeated calls with identical input produce identical output. The expression is compiled once and then applied to each line, but regular expressions can still become computationally expensive when they contain ambiguous nested repetition.
Prefer anchored, specific patterns for large inputs, and avoid expressions known to cause excessive backtracking. Review the returned text when designing a rule, and use the counts as a guard in automation—for example, stop a deployment when a cleanup intended to remove one generated line reports hundreds.
What you can do with it
Remove noisy log entries
Discard recurring debug, health-check, or monitoring lines while preserving the events that need investigation.
Clean generated source text
Strip matching banner comments, generator markers, or environment-specific lines before reviewing a meaningful diff.
Filter line-oriented records
Exclude headers, trailers, comments, or unwanted record prefixes from exports before another processing step.
FAQ
What regular expression syntax does it use?
It uses JavaScript regular-expression syntax. Supply the pattern without surrounding slash delimiters.
Does the pattern match the newline character?
No. Each expression is tested against the content of one line, excluding its line ending.
Are matching lines replaced with blank lines?
No. Matching lines and their attached line endings are removed; retained lines are returned unchanged.
Can it remove empty or whitespace-only lines?
Yes. Use ^$ for empty lines or ^\s*$ for lines containing only whitespace.
How do I remove only the lines that start with a certain word?
Put ^ before the word, as in ^DEBUG. Without it, a line is removed whenever the word appears anywhere in it. Matching is case-sensitive, so DEBUG and debug count as different words.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/str/remove-lines-matching \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"INFO Server started\nDEBUG Cache miss\nERROR Connection lost\nDEBUG Retrying\nINFO Server ready","pattern":"^DEBUG\\b"}'const res = await fetch("https://api.kit.forhosting.com/str/remove-lines-matching", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "INFO Server started\nDEBUG Cache miss\nERROR Connection lost\nDEBUG Retrying\nINFO Server ready",
"pattern": "^DEBUG\\b"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/str/remove-lines-matching",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "INFO Server started\nDEBUG Cache miss\nERROR Connection lost\nDEBUG Retrying\nINFO Server ready",
"pattern": "^DEBUG\\b"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/str/remove-lines-matching", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"INFO Server started\\nDEBUG Cache miss\\nERROR Connection lost\\nDEBUG Retrying\\nINFO Server ready","pattern":"^DEBUG\\\\b"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"INFO Server started\nDEBUG Cache miss\nERROR Connection lost\nDEBUG Retrying\nINFO Server ready","pattern":"^DEBUG\\b"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/str/remove-lines-matching", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"text": "INFO Server started\nDEBUG Cache miss\nERROR Connection lost\nDEBUG Retrying\nINFO Server ready",
"pattern": "^DEBUG\\b"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "str.remove_lines_matching",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
Write a pattern for the complete line you want to remove
Escapes inside JSON need the normal JSON treatment, so a backslash is represented twice in a raw JSON request.
Understand exactly what happens to line endings and empty lines
The response includes removed_count and kept_count, allowing a script to reject an unexpectedly broad edit.
Use deterministic filtering safely in logs, code, and pipelines
Invalid regular-expression syntax is rejected as <code>invalid_input</code> instead of returning partially filtered text. API requests cost $0.002; the browser version runs locally for interactive work.
Technical questions
What happens when the pattern is invalid?
The request fails with an invalid_input error that identifies the pattern as an invalid regular expression.
How much does an API request cost?
Each API request costs $0.002. Interactive filtering is also available in the browser.