Regular Expressions 101

Save & Share

Flavor

  • PCRE2 (PHP >=7.3)
  • PCRE (PHP <7.3)
  • ECMAScript (JavaScript)
  • Python
  • Golang
  • Java 8

Function

  • Match
  • Substitution
  • List
  • Unit Tests
@
(?(DEFINE) (?<next_open_tag> [^<]*+ (?i: <++[^<?s][^<]* | <++(?! \?php | \?= | script\s*language\s*=\s*([\'"]?)php\g{-1}\s*> ) [^<]* )*+ (?i: <++(?: \?php | \?= | [^>]+ ) | \z ) ) ) \A (?&next_open_tag) \K | [^'"`/#<?]*+ (?: '(?:[^'\\]+|\\.)*+' [^\'"`/#<?]* | "(?:[^"\\]+|\\.)*+" [^\'"`/#<?]* | `(?:[^`\\]+|\\.)*+` [^\'"`/#<?]* | /(?![/*]) [^\'"`/#<?]* # stop for // or /* | # if close tag ?> \? (?: >(?&next_open_tag)[^\'"`/#<?]* | ) | < (?: # heredoc or nowdoc <<[\ \t]*([\'"]?) ([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*) \g{-2}[\ \t]*[\r\n] (?-s:.*+[\r\n])*? \g{-1}[\r\n;] [^\'"`/#<?]* | (?i: /script\s*>) (?&next_open_tag) [^\'"`/#<?]* | [^\'"`/#<?]* ) )*+ \K (?: (?://|\#)(?:[^\n?]+|\?(?!>))*+ # single line comment // и # | /\*(?:[^*]+|\*(?!/))*+\*/ # multi line comment /* */ )?
@
xsg
1st Alternative
(?(DEFINE) (?<next_open_tag> [^<]*+ (?i: <++[^<?s][^<]* | <++(?! \?php | \?= | script\s*language\s*=\s*([\'"]?)php\g{-1}\s*> ) [^<]* )*+ (?i: <++(?: \?php | \?= | [^>]+ ) | \z ) ) ) \A (?&next_open_tag) \K
Subpattern definition construct
(?(DEFINE) (?<next_open_tag> [^<]*+ (?i: <++[^<?s][^<]* | <++(?! \?php | \?= | script\s*language\s*=\s*([\'"]?)php\g{-1}\s*> ) [^<]* )*+ (?i: <++(?: \?php | \?= | [^>]+ ) | \z ) ) )
May only be used to define functions. No matching is done in this group.
Named Capture Group next_open_tag
(?<next_open_tag> [^<]*+ (?i: <++[^<?s][^<]* | <++(?! \?php | \?= | script\s*language\s*=\s*([\'"]?)php\g{-1}\s*> ) [^<]* )*+ (?i: <++(?: \?php | \?= | [^>]+ ) | \z ) )
Match a single character not present in the list below
[^<]
*+ matches the previous token between zero and unlimited times, as many times as possible, without giving back (possessive)
< matches the character < with index 6010 (3C16 or 748) literally (case sensitive)
Non-capturing Group. Matches the tokens contained with the following effective flags: xsgi
(?i: <++[^<?s][^<]* | <++(?! \?php | \?= | script\s*language\s*=\s*([\'"]?)php\g{-1}\s*> ) [^<]* )*+
i modifier: insensitive. Case insensitive match (ignores case of [a-zA-Z])
*+ matches the previous token between zero and unlimited times, as many times as possible, without giving back (possessive)
1st Alternative
<++[^<?s][^<]*
<
matches the character < with index 6010 (3C16 or 748) literally (case insensitive)
Match a single character not present in the list below
[^<?s]
<?s
matches a single character in the list <?s (case insensitive)
Match a single character not present in the list below
[^<]
* matches the previous token between zero and unlimited times, as many times as possible, giving back as needed (greedy)
< matches the character < with index 6010 (3C16 or 748) literally (case insensitive)
2nd Alternative
<++(?! \?php | \?= | script\s*language\s*=\s*([\'"]?)php\g{-1}\s*> ) [^<]*
<
matches the character < with index 6010 (3C16 or 748) literally (case insensitive)
Negative Lookahead
(?! \?php | \?= | script\s*language\s*=\s*([\'"]?)php\g{-1}\s*> )
Assert that the Regex below does not match
1st Alternative
\?php
\? matches the character ? with index 6310 (3F16 or 778) literally (case insensitive)
php
matches the characters php literally (case insensitive)
2nd Alternative
\?=
\? matches the character ? with index 6310 (3F16 or 778) literally (case insensitive)
=
matches the character = with index 6110 (3D16 or 758) literally (case insensitive)
3rd Alternative
script\s*language\s*=\s*([\'"]?)php\g{-1}\s*>
script
matches the characters script literally (case insensitive)
\s
matches any whitespace character (equivalent to [\r\n\t\f\v ])
* matches the previous token between zero and unlimited times, as many times as possible, giving back as needed (greedy)
language
matches the characters language literally (case insensitive)
\s
matches any whitespace character (equivalent to [\r\n\t\f\v ])
* matches the previous token between zero and unlimited times, as many times as possible, giving back as needed (greedy)
= matches the character = with index 6110 (3D16 or 758) literally (case insensitive)
\s
matches any whitespace character (equivalent to [\r\n\t\f\v ])
* matches the previous token between zero and unlimited times, as many times as possible, giving back as needed (greedy)
2nd Capturing Group
([\'"]?)
Match a single character present in the list below
[\'"]
? matches the previous token between zero and one times, as many times as possible, giving back as needed (greedy)
\' matches the character ' with index 3910 (2716 or 478) literally (case insensitive)
" matches the character " with index 3410 (2216 or 428) literally (case insensitive)
php
matches the characters php literally (case insensitive)
\g{-1} matches the same text as most recently matched by the 2nd capturing group
\s
matches any whitespace character (equivalent to [\r\n\t\f\v ])
>
matches the character > with index 6210 (3E16 or 768) literally (case insensitive)
Match a single character not present in the list below
[^<]
* matches the previous token between zero and unlimited times, as many times as possible, giving back as needed (greedy)
< matches the character < with index 6010 (3C16 or 748) literally (case insensitive)
Non-capturing Group. Matches the tokens contained with the following effective flags: xsgi
(?i: <++(?: \?php | \?= | [^>]+ ) | \z )
i modifier: insensitive. Case insensitive match (ignores case of [a-zA-Z])
1st Alternative
<++(?: \?php | \?= | [^>]+ )
<
matches the character < with index 6010 (3C16 or 748) literally (case insensitive)
Non-capturing group
(?: \?php | \?= | [^>]+ )
1st Alternative
\?php
\? matches the character ? with index 6310 (3F16 or 778) literally (case insensitive)
php
matches the characters php literally (case insensitive)
2nd Alternative
\?=
\? matches the character ? with index 6310 (3F16 or 778) literally (case insensitive)
=
matches the character = with index 6110 (3D16 or 758) literally (case insensitive)
3rd Alternative
[^>]+
Match a single character not present in the list below
[^>]
+ matches the previous token between one and unlimited times, as many times as possible, giving back as needed (greedy)
> matches the character > with index 6210 (3E16 or 768) literally (case insensitive)
2nd Alternative
\z
\z asserts position at the end of the string
\A asserts position at start of the string
(?&next_open_tag) recurses the subpattern named next_open_tag
\K resets the starting point of the reported match. Any previously consumed characters are no longer included in the final match
2nd Alternative
[^'"`/#<?]*+ (?: '(?:[^'\\]+|\\.)*+' [^\'"`/#<?]* | "(?:[^"\\]+|\\.)*+" [^\'"`/#<?]* | `(?:[^`\\]+|\\.)*+` [^\'"`/#<?]* | /(?![/*]) [^\'"`/#<?]* # stop for // or /* | # if close tag ?> \? (?: >(?&next_open_tag)[^\'"`/#<?]* | ) | < (?: # heredoc or nowdoc <<[\ \t]*([\'"]?) ([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*) \g{-2}[\ \t]*[\r\n] (?-s:.*+[\r\n])*? \g{-1}[\r\n;] [^\'"`/#<?]* | (?i: /script\s*>) (?&next_open_tag) [^\'"`/#<?]* | [^\'"`/#<?]* ) )*+ \K (?: (?://|\#)(?:[^\n?]+|\?(?!>))*+ # single line comment // и # | /\*(?:[^*]+|\*(?!/))*+\*/ # multi line comment /* */ )?
Match a single character not present in the list below
[^'"`/#<?]
*+ matches the previous token between zero and unlimited times, as many times as possible, without giving back (possessive)
'"`/#<?
matches a single character in the list '"`/#<? (case sensitive)
Non-capturing group
(?: '(?:[^'\\]+|\\.)*+' [^\'"`/#<?]* | "(?:[^"\\]+|\\.)*+" [^\'"`/#<?]* | `(?:[^`\\]+|\\.)*+` [^\'"`/#<?]* | /(?![/*]) [^\'"`/#<?]* # stop for // or /* | # if close tag ?> \? (?: >(?&next_open_tag)[^\'"`/#<?]* | ) | < (?: # heredoc or nowdoc <<[\ \t]*([\'"]?) ([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*) \g{-2}[\ \t]*[\r\n] (?-s:.*+[\r\n])*? \g{-1}[\r\n;] [^\'"`/#<?]* | (?i: /script\s*>) (?&next_open_tag) [^\'"`/#<?]* | [^\'"`/#<?]* ) )*+
*+ matches the previous token between zero and unlimited times, as many times as possible, without giving back (possessive)
1st Alternative
'(?:[^'\\]+|\\.)*+' [^\'"`/#<?]*
'
matches the character ' with index 3210 (2016 or 408) literally (case sensitive)
Non-capturing group
(?:[^'\\]+|\\.)*+
*+ matches the previous token between zero and unlimited times, as many times as possible, without giving back (possessive)
1st Alternative
[^'\\]+
Match a single character not present in the list below
[^'\\]
+ matches the previous token between one and unlimited times, as many times as possible, giving back as needed (greedy)
' matches the character ' with index 3910 (2716 or 478) literally (case sensitive)
\\ matches the character \ with index 9210 (5C16 or 1348) literally (case sensitive)
2nd Alternative
\\.
\\ matches the character \ with index 9210 (5C16 or 1348) literally (case sensitive)
. matches any character
'
matches the character ' with index 3910 (2716 or 478) literally (case sensitive)
Match a single character not present in the list below
[^\'"`/#<?]
* matches the previous token between zero and unlimited times, as many times as possible, giving back as needed (greedy)
\' matches the character ' with index 3910 (2716 or 478) literally (case sensitive)
"`/#<?
matches a single character in the list "`/#<? (case sensitive)
2nd Alternative
"(?:[^"\\]+|\\.)*+" [^\'"`/#<?]*
"
matches the character " with index 3210 (2016 or 408) literally (case sensitive)
Non-capturing group
(?:[^"\\]+|\\.)*+
*+ matches the previous token between zero and unlimited times, as many times as possible, without giving back (possessive)
1st Alternative
[^"\\]+
Match a single character not present in the list below
[^"\\]
+ matches the previous token between one and unlimited times, as many times as possible, giving back as needed (greedy)
" matches the character " with index 3410 (2216 or 428) literally (case sensitive)
\\ matches the character \ with index 9210 (5C16 or 1348) literally (case sensitive)
2nd Alternative
\\.
\\ matches the character \ with index 9210 (5C16 or 1348) literally (case sensitive)
. matches any character
"
matches the character " with index 3410 (2216 or 428) literally (case sensitive)
Match a single character not present in the list below
[^\'"`/#<?]
* matches the previous token between zero and unlimited times, as many times as possible, giving back as needed (greedy)
\' matches the character ' with index 3910 (2716 or 478) literally (case sensitive)
"`/#<?
matches a single character in the list "`/#<? (case sensitive)
3rd Alternative
`(?:[^`\\]+|\\.)*+` [^\'"`/#<?]*
`
matches the character ` with index 3210 (2016 or 408) literally (case sensitive)
Non-capturing group
(?:[^`\\]+|\\.)*+
*+ matches the previous token between zero and unlimited times, as many times as possible, without giving back (possessive)
1st Alternative
[^`\\]+
Match a single character not present in the list below
[^`\\]
+ matches the previous token between one and unlimited times, as many times as possible, giving back as needed (greedy)
` matches the character ` with index 9610 (6016 or 1408) literally (case sensitive)
\\ matches the character \ with index 9210 (5C16 or 1348) literally (case sensitive)
2nd Alternative
\\.
\\ matches the character \ with index 9210 (5C16 or 1348) literally (case sensitive)
. matches any character
`
matches the character ` with index 9610 (6016 or 1408) literally (case sensitive)
Match a single character not present in the list below
[^\'"`/#<?]
* matches the previous token between zero and unlimited times, as many times as possible, giving back as needed (greedy)
\' matches the character ' with index 3910 (2716 or 478) literally (case sensitive)
"`/#<?
matches a single character in the list "`/#<? (case sensitive)
4th Alternative
/(?![/*]) [^\'"`/#<?]* # stop for // or /*
/
matches the character / with index 3210 (2016 or 408) literally (case sensitive)
Negative Lookahead
(?![/*])
Assert that the Regex below does not match
Match a single character present in the list below
[/*]
/*
matches a single character in the list /* (case sensitive)
Match a single character not present in the list below
[^\'"`/#<?]
* matches the previous token between zero and unlimited times, as many times as possible, giving back as needed (greedy)
\' matches the character ' with index 3910 (2716 or 478) literally (case sensitive)
"`/#<?
matches a single character in the list "`/#<? (case sensitive)
# stop for // or /*
stop for // or /*
Comment: stop for // or /*
5th Alternative
# if close tag ?> \? (?: >(?&next_open_tag)[^\'"`/#<?]* | )
# if close tag ?>
if close tag ?>
Comment: if close tag ?>
\? matches the character ? with index 6310 (3F16 or 778) literally (case sensitive)
Non-capturing group
(?: >(?&next_open_tag)[^\'"`/#<?]* | )
1st Alternative
>(?&next_open_tag)[^\'"`/#<?]*
>
matches the character > with index 3210 (2016 or 408) literally (case sensitive)
(?&next_open_tag) recurses the subpattern named next_open_tag
Match a single character not present in the list below
[^\'"`/#<?]
* matches the previous token between zero and unlimited times, as many times as possible, giving back as needed (greedy)
\' matches the character ' with index 3910 (2716 or 478) literally (case sensitive)
"`/#<?
matches a single character in the list "`/#<? (case sensitive)
2nd Alternative
6th Alternative
< (?: # heredoc or nowdoc <<[\ \t]*([\'"]?) ([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*) \g{-2}[\ \t]*[\r\n] (?-s:.*+[\r\n])*? \g{-1}[\r\n;] [^\'"`/#<?]* | (?i: /script\s*>) (?&next_open_tag) [^\'"`/#<?]* | [^\'"`/#<?]* )
<
matches the character < with index 3210 (2016 or 408) literally (case sensitive)
Non-capturing group
(?: # heredoc or nowdoc <<[\ \t]*([\'"]?) ([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*) \g{-2}[\ \t]*[\r\n] (?-s:.*+[\r\n])*? \g{-1}[\r\n;] [^\'"`/#<?]* | (?i: /script\s*>) (?&next_open_tag) [^\'"`/#<?]* | [^\'"`/#<?]* )
1st Alternative
# heredoc or nowdoc <<[\ \t]*([\'"]?) ([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*) \g{-2}[\ \t]*[\r\n] (?-s:.*+[\r\n])*? \g{-1}[\r\n;] [^\'"`/#<?]*
# heredoc or nowdoc <<
heredoc or nowdoc
Comment: heredoc or nowdoc
< matches the character < with index 6010 (3C16 or 748) literally (case sensitive)
< matches the character < with index 6010 (3C16 or 748) literally (case sensitive)
Match a single character present in the list below
[\ \t]
* matches the previous token between zero and unlimited times, as many times as possible, giving back as needed (greedy)
\ matches the character with index 3210 (2016 or 408) literally (case sensitive)
\t matches a tab character (ASCII 9)
3rd Capturing Group
([\'"]?)
Match a single character present in the list below
[\'"]
? matches the previous token between zero and one times, as many times as possible, giving back as needed (greedy)
\' matches the character ' with index 3910 (2716 or 478) literally (case sensitive)
" matches the character " with index 3410 (2216 or 428) literally (case sensitive)
4th Capturing Group
([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)
\g{-2} matches the same text as most recently matched by the 3rd capturing group
Match a single character present in the list below
[\ \t]
Match a single character present in the list below
[\r\n]
Non-capturing Group. Matches the tokens contained with the following effective flags: xg
(?-s:.*+[\r\n])*?
\g{-1} matches the same text as most recently matched by the 4th capturing group
Match a single character present in the list below
[\r\n;]
Match a single character not present in the list below
[^\'"`/#<?]
2nd Alternative
(?i: /script\s*>) (?&next_open_tag) [^\'"`/#<?]*
Non-capturing Group. Matches the tokens contained with the following effective flags: xsgi
(?i: /script\s*>)
i modifier: insensitive. Case insensitive match (ignores case of [a-zA-Z])
/script
matches the characters /script literally (case insensitive)
\s
matches any whitespace character (equivalent to [\r\n\t\f\v ])
* matches the previous token between zero and unlimited times, as many times as possible, giving back as needed (greedy)
> matches the character > with index 6210 (3E16 or 768) literally (case insensitive)
(?&next_open_tag) recurses the subpattern named next_open_tag
Match a single character not present in the list below
[^\'"`/#<?]
* matches the previous token between zero and unlimited times, as many times as possible, giving back as needed (greedy)
\' matches the character ' with index 3910 (2716 or 478) literally (case sensitive)
"`/#<?
matches a single character in the list "`/#<? (case sensitive)
3rd Alternative
[^\'"`/#<?]*
Match a single character not present in the list below
[^\'"`/#<?]
* matches the previous token between zero and unlimited times, as many times as possible, giving back as needed (greedy)
\' matches the character ' with index 3910 (2716 or 478) literally (case sensitive)
"`/#<?
matches a single character in the list "`/#<? (case sensitive)
\K resets the starting point of the reported match. Any previously consumed characters are no longer included in the final match
Non-capturing group
(?: (?://|\#)(?:[^\n?]+|\?(?!>))*+ # single line comment // и # | /\*(?:[^*]+|\*(?!/))*+\*/ # multi line comment /* */ )?
? matches the previous token between zero and one times, as many times as possible, giving back as needed (greedy)
1st Alternative
(?://|\#)(?:[^\n?]+|\?(?!>))*+ # single line comment // и #
Non-capturing group
(?://|\#)
1st Alternative
//
//
matches the characters // literally (case sensitive)
2nd Alternative
\#
\# matches the character # with index 3510 (2316 or 438) literally (case sensitive)
Non-capturing group
(?:[^\n?]+|\?(?!>))*+
*+ matches the previous token between zero and unlimited times, as many times as possible, without giving back (possessive)
1st Alternative
[^\n?]+
Match a single character not present in the list below
[^\n?]
+ matches the previous token between one and unlimited times, as many times as possible, giving back as needed (greedy)
\n matches a line-feed (newline) character (ASCII 10)
? matches the character ? with index 6310 (3F16 or 778) literally (case sensitive)
2nd Alternative
\?(?!>)
\? matches the character ? with index 6310 (3F16 or 778) literally (case sensitive)
Negative Lookahead
(?!>)
Assert that the Regex below does not match
> matches the character > with index 6210 (3E16 or 768) literally (case sensitive)
# single line comment // и #
single line comment // и #
Comment: single line comment // и #
2nd Alternative
/\*(?:[^*]+|\*(?!/))*+\*/ # multi line comment /* */
/
matches the character / with index 3210 (2016 or 408) literally (case sensitive)
\* matches the character * with index 4210 (2A16 or 528) literally (case sensitive)
Non-capturing group
(?:[^*]+|\*(?!/))*+
*+ matches the previous token between zero and unlimited times, as many times as possible, without giving back (possessive)
1st Alternative
[^*]+
Match a single character not present in the list below
[^*]
+ matches the previous token between one and unlimited times, as many times as possible, giving back as needed (greedy)
* matches the character * with index 4210 (2A16 or 528) literally (case sensitive)
2nd Alternative
\*(?!/)
\* matches the character * with index 4210 (2A16 or 528) literally (case sensitive)
Negative Lookahead
(?!/)
Assert that the Regex below does not match
/ matches the character / with index 4710 (2F16 or 578) literally (case sensitive)
\* matches the character * with index 4210 (2A16 or 528) literally (case sensitive)
/
matches the character / with index 4710 (2F16 or 578) literally (case sensitive)
# multi line comment /* */
multi line comment /* */
Comment: multi line comment /* */
Global pattern flags
x modifier: extended. Spaces and text after a # in the pattern are ignored
s modifier: single line. Dot matches newline characters
g modifier: global. All matches (don't return after first match)
Your regular expression does not match the subject string.Try launching the debugger to find out why.

Regular Expression
No Match

@
@
xsg

Test String

Substitution

Processing...