Regex and cron

Regex to Trim Leading and Trailing Whitespace

Trim spaces, tabs and line breaks from both ends of a string, and avoid the slow version.

  • Free foreverNo trial, no paywall, no usage limits.
  • No sign-upOpen the page and start. We never ask for an email to use a tool.
  • PrivateEverything runs in your browser. Your input is never uploaded or stored on our servers.
  • Works offlineOnce the page has loaded, the tool keeps working without a connection.

Pattern

/^\s+|\s+$/g
  • g globalFind every match instead of stopping at the first. Needed for matchAll() and for replacing all occurrences.

Regular expression

JavaScript syntax, run by your browser's own engine in a background worker. Press / anywhere to jump here.
Reset to the original pattern and examplesShow cheat sheet: click any token to insert itCopy pattern
Find every match instead of stopping at the first. Needed for matchAll() and for replacing all occurrences.Case-insensitive: /abc/i also matches "ABC" and "aBc".^ and $ match at the start and end of every line, not just the whole string. Use it to test one value per line.Lets . match line breaks too. Without it, . stops at \n and \r.Treats the pattern as Unicode code points: enables \p{…} property escapes and \u{…}, makes emoji count as one character, and rejects sloppy escapes.Only matches starting exactly at lastIndex (position 0 here), never further along. Useful for tokenizers that consume input piece by piece.Records the start and end index of every capture group (match.indices). The tester always shows group positions, so this only changes your code.The upgraded unicode mode (ES2024): set operations like [\p{L}--[a-z]] and [A&&B], string properties like \p{RGI_Emoji}. Cannot be combined with u.
6 matches6 matches

Test string

Matches are highlighted as you type, in alternating colors. Click inside a match (or hover its row below) to color its capture groups.
6 matchesClear test string

Explanation

Every part of the pattern in plain English. Hover a row to highlight that part of the pattern.
Copy explanation

Loading the explainer…

Every match with its position and capture groups.Preview a replacement with $1, $<name> and $& references, then copy the result.Copy a ready-to-run snippet for JavaScript, Python, Go, C#, PHP or Dart.

Matches

Named groups are shown by name. undefined means the group did not take part in that match.
Copy matches as JSONDownload matches.csv
#MatchPosition
1···0–3
2···33–36
3→37–38
4→56–57
5··58–60
6··70–72

Need a secure web app built around this? Talk to our team

Quick answer

To trim whitespace with a regex, replace ^\s+|\s+$ with an empty string using the g flag: the first alternative removes spaces, tabs and line breaks at the start, the second removes them at the end, and inner spaces are left alone. In JavaScript, String.prototype.trim() does the same job faster, so use the regex when you need a variant such as trimming every line with the m flag.

  • Tested examples
  • Token-by-token breakdown
  • Code in 5 languages
  • Live tester

How to use the leading and trailing whitespace regex

  1. 1Copy the pattern with Copy pattern in the tester, or take a snippet for your language from the code section below.
  2. 2Look at the sample in Test string: every leading and trailing whitespace the regex finds is highlighted.
  3. 3Paste your own text to see the matches, then switch to Replace to preview a replacement.
  4. 4Open the Code tab for JavaScript, Python, Go, C#, PHP or Dart with the pattern translated and escaped.

How does the leading and trailing whitespace regex work?

Read it left to right. Each piece below matches one part of the input:

  • ^\s+ One or more whitespace characters at the start of the string.
  • | Or.
  • \s+$ One or more whitespace characters at the end of the string.
  • g flag Global, so both the leading and the trailing run are replaced, not just the first.

Flags: g (global).

Which strings does the leading and trailing whitespace regex match?

The pattern searches inside the text, so a match can be part of a longer string. Every row below is checked against the pattern by our automated test suite before each release.

InputFinds a match?Why
··hello·world··YesSpaces at both ends are matched; the inner space is not.
→helloYesA leading tab.
hello↵YesA trailing newline, typical of file contents.
hello·worldNoNothing to trim: the inner space is untouched.
helloNoNo whitespace at all.
a·b→cNoWhitespace between words only: nothing at either end.

Replacing every match with an empty string (text.replace(regex, "")):

BeforeAfter
··hello·world··hello·world
→hellohello
hello↵hello
·↵→·padded·→↵·padded

Why can this regex be slow on long strings?

The second alternative, \s+$, is the classic trap. Given a long run of spaces that is not at the end (say 20,000 spaces followed by a letter), the engine starts at every space, consumes the rest of the run, fails to find the end, and backs off one character at a time. That is quadratic work: the run of spaces is scanned again from every starting position.

A pattern of this shape (^[\s\u200c]+|[\s\u200c]+$) took Stack Overflow offline for 34 minutes on July 20, 2016, when a post with about 20,000 consecutive whitespace characters reached the home page. Two fixes:

  1. Use the built-in: str.trim() in JavaScript, str.strip() in Python, strings.TrimSpace in Go, String.Trim() in C#, trim() in PHP. They scan from each end and never backtrack.
  2. If you need a regex, trim the end with a non-backtracking approach, or cap the input length first.

How do I trim every line, or collapse inner spaces?

Common variations, all used with replace:

  • Trim every line: ^[ \t]+|[ \t]+$ with flags gm, replaced with an empty string.
  • Collapse runs of spaces: [ \t]{2,} with g, replaced with a single space.
  • Remove blank lines: ^\s*\n with gm, replaced with an empty string.
  • Normalize all whitespace: \s+ with g, replaced with a single space, then trimmed.

Use [ \t] rather than \s in multiline mode, because \s also matches the line breaks and would join lines together. In JavaScript, \s covers Unicode spaces such as the non-breaking space (U+00A0) as well, which is usually what you want when cleaning pasted text.

How do I use the leading and trailing whitespace regex in JavaScript, Python, Go, C# and PHP?

The pattern is translated for each engine rather than pasted as is: named groups, anchors, escapes, shorthand classes and flags are adjusted so each snippet behaves as closely to the JavaScript version as its engine allows. Differences that remain (Go's RE2 has no lookarounds or backreferences, for example) are called out under each one. The Code tab in the tester above also exports Dart, and updates as you edit the pattern.

JavaScript and TypeScript

const regex = /^\s+|\s+$/g;
const text = "  hello world  ";

for (const match of text.matchAll(regex)) {
  console.log(match[0], "at index", match.index);
}

const result = text.replace(regex, "");
console.log(result);

Python

import re

pattern = re.compile(r"^\s+|\s+\Z")
text = "  hello world  "

for match in pattern.finditer(text):
    print(match.group(0), "at index", match.start())

result = pattern.sub(r"", text)
print(result)
  • JavaScript's $ only matches at the very end of the string. Python's $ also matches before a trailing newline, so the pattern uses \Z instead.

Go

package main

import (
	"fmt"
	"regexp"
)

func main() {
	re := regexp.MustCompile(`^\s+|\s+$`)
	text := "  hello world  "

	for _, m := range re.FindAllStringSubmatch(text, -1) {
		fmt.Println(m[0])
	}

	result := re.ReplaceAllString(text, "")
	fmt.Println(result)
}
  • Go's \s only matches space, \t, \n, \f and \r; JavaScript's also matches the non-breaking space and other Unicode spaces.

C#

using System;
using System.Text.RegularExpressions;

// The timeout stops a pathological input from hanging the thread (ReDoS).
var regex = new Regex(@"^\s+|\s+\z", RegexOptions.None, TimeSpan.FromSeconds(1));
var text = "  hello world  ";

foreach (Match match in regex.Matches(text))
{
    Console.WriteLine($"{match.Value} at index {match.Index}");
}

var result = regex.Replace(text, @"");
Console.WriteLine(result);
  • JavaScript's $ only matches at the very end of the string. .NET's $ also matches before a trailing newline, so the pattern uses \z instead.

PHP

<?php

$pattern = '/^\s+|\s+$/D';
$text = '  hello world  ';

preg_match_all($pattern, $text, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
foreach ($matches as $match) {
    echo $match[0][0], " at index ", $match[0][1], PHP_EOL;
}

$result = preg_replace($pattern, '', $text);
echo $result, PHP_EOL;
  • PCRE's \s matches ASCII whitespace unless Unicode properties (UCP) are on; JavaScript's also matches the non-breaking space and other Unicode spaces.
  • The D modifier makes $ match only at the very end, like JavaScript (PCRE's $ also matches before a trailing newline).

Browse all 25 patterns in the regex pattern library, or build your own in the regex tester.

Frequently asked questions

trim() is faster, clearer and cannot backtrack. Reach for the regex only for variants trim() does not cover, such as trimming every line of a text with the m flag.
Without g, replace() only replaces the first match, so it would remove the leading whitespace and leave the trailing whitespace in place.
In JavaScript, yes: \s matches Unicode whitespace including U+00A0 and the line and paragraph separators. In other engines it may only match ASCII whitespace unless Unicode mode is on.

Last updated by the Playxoft engineering team.

From the engineers who built this tool

Building something bigger than a quick fix?

Auth, payments, dashboards and security are where web apps get hard. We have shipped them many times. Share your idea and we will map out a realistic plan and estimate, free and with no obligation.

More free tools

See all tools

Regex Tester

Test regex live with highlighted matches, plain-English explanations and code export.

Open tool

Cron Expression Generator

New

Build and explain cron schedules, see the next runs in any time zone, copy platform snippets.

Open tool

SQL Formatter

Beautify or minify SQL in 12 dialects, with keyword case, indent and line:column errors.

Open tool

cURL to Python Converter

New

Convert cURL commands into Python requests or httpx code with params, json, files and auth.

Open tool

cURL to Fetch Converter

New

Turn any cURL command into JavaScript fetch() code with headers, JSON, forms and auth.

Open tool

cURL to Axios Converter

New

Convert cURL commands into an Axios request config with params, data, auth and timeouts.

Open tool