Regular Expressions 101

Save & Share

  • Regex Version: ver. 7
  • Update Regex
    ctrl+⇧+s
  • Save new Regex
    ctrl+s
  • Add to Community Library

Flavor

  • PCRE2 (PHP >=7.3)
  • PCRE (PHP <7.3)
  • ECMAScript (JavaScript)
  • Python
  • Golang
  • Java 8
  • .NET 7.0 (C#)
  • Rust
  • Regex Flavor Guide

Function

  • Match
  • Substitution
  • List
  • Unit Tests

Tools

Sponsors
There are currently no sponsors. Become a sponsor today!
An explanation of your regex will be automatically generated as you type.
Detailed match information will be displayed here automatically.
  • All Tokens
  • Common Tokens
  • General Tokens
  • Anchors
  • Meta Sequences
  • Quantifiers
  • Group Constructs
  • Character Classes
  • Flags/Modifiers
  • Substitution
  • A single character of: a, b or c
    [abc]
  • A character except: a, b or c
    [^abc]
  • A character in the range: a-z
    [a-z]
  • A character not in the range: a-z
    [^a-z]
  • A character in the range: a-z or A-Z
    [a-zA-Z]
  • Any single character
    .
  • Alternate - match either a or b
    a|b
  • Any whitespace character
    \s
  • Any non-whitespace character
    \S
  • Any digit
    \d
  • Any non-digit
    \D
  • Any word character
    \w
  • Any non-word character
    \W
  • Non-capturing group
    (?:...)
  • Capturing group
    (...)
  • Zero or one of a
    a?
  • Zero or more of a
    a*
  • One or more of a
    a+
  • Exactly 3 of a
    a{3}
  • 3 or more of a
    a{3,}
  • Between 3 and 6 of a
    a{3,6}
  • Start of string
    ^
  • End of string
    $
  • A word boundary
    \b
  • Non-word boundary
    \B

Regular Expression

/
/
gxA

Test String

Code Generator

Generated Code

import Foundation // WARNING: You included a flag that Swift doesn't support: A // When this flag is set, it causes the pattern to be "anchored", that is, it is constrained to match only at the start of the string which is being searched (the "subject string"). // As an alternative, this effect can also be achieved by appropriate constructs in the pattern itself. let pattern = ##""" # Chess game validation regex (PCRE) (?!^(?!rnbqkbnr\np{8}(?:\n-{8}){4}\nP{8}\nRNBQKBNR\n\n)) # assert initial state of board, if this is the first move (?> (\n)? # \1 = capture \n if black moves next (ensuring that white moves first), or unset/NPCG if white moves next | # subroutines: ((.|\n(?=.)){2}) # (?3) = for moving within the board, without wrapping to the next board, (?2) = (?3){2} ((?= # (?4) = assert that position of just-consumed piece is vacated on the next turn (\X{72}) # (?5) = skip to the position of the just-consumed piece on the next turn -)) ((?! # (?6) = assert that the piece at the current position belongs to the current player ((?=(?(1)[-A-Z]|[-a-z]))) # (?7) = assert that the piece at the current position belongs to the current player's opponent or is empty )) ((?5)(?(?=(.*\n)\n)[qnrb]|p)) # (?8) = black pawn that might be promoted, (?9) = .*\n ( # (?10) = assert that the just-consumed piece never moved in all past turns (?<=(.)) ((?<!(?!_|\11(?12))\PM{74})) ) ((?5)(?(?=(?9){8}\n)[QNRB]|P)) # (?13) = white pawn that might be promoted ) ( # check if we're in check; \14 will be captured and empty if we're not in check, or unset if we are; call (?14) to assert we're not in check on the next turn (?! \X{,70} (?: # pawns (capture diagonally) (?(1)k|p)(?=(?3){7}(?2)?(?(1)P|K)) | # bishops, rooks, queens, or knights (?i: (?<E>(?6)K)? # decide between scanning forward (<E> is unset) or backwards (<E> is captured) (?: (?(E)|((?7)[BQ])) (?<B>()?((?(-1)-)(?3){7}(?(-2)(?2)))+) (?(E)(?-4)) | # bishops or queens (?(E)|((?7)[RQ])) (?<R>-*|((?(-1)-)(?3){8})+) (?(E)(?-3)) | # rooks or queens (?(E)|((?7) N )) (?<N>(?<=..)(?2){3}|(?=.)(?2){5}|(?2){8}(?2)?) (?(E)(?-2)) # knights ) (?(E)|(?&E)) | K(?<K>(?3){7,9})?K # kings ) ) ) )?? (?> (?> # Handle squares that don't change (empty->empty or pieces that doesn't move) (.)(?=(?5)\g{-1}) | # Handle a piece that moves (and optionally captures an enemy piece) (?(m)$) # allow only one move to be made per turn (?> (?(1) (?:p(?4)(?: # black pawn (?=(?3){8}((?3){9})? - (?8))(?(-1)(?=(?9){7}\n)) | # move 1 or 2 spaces forward (?=(?3){7}(?2)? [A-Z](?8)) ) | # capture diagonally (?=\X{73}--(?9){4}\n)(?|P(?=(p))|pP())(?<=(?=(?:-\X{8}){2}P)\PM{74}(?=\X{8}-(?5)p))\g{-1} ) # en passant | (?: # white pawn - (?=(?13))(?=(?3){8}((?3){9})?P(?4))(?(-1)(?=(?9){4}\n)) | # move 1 or 2 spaces forward [a-z](?=(?13))(?=(?3){7}(?2)? P(?4)) | # capture diagonally (?=\X{73}--(?9){5}\n)(?|p(?=(P))|Pp())(?<=(?=p(?:\X{8}-){2})\PM{82}(?=-(?5)P)\PM{10})\g{-1} ) # en passant ) | # Castling - must be tried before rook moves unless we give up atomicity # Leaves the rightmost changed square unconsumed, so that "only allow matching one of these per turn" below can't silently consume an illegal move (?6)([KkRr])(?10) (?! (?:--)?- # Verify that we aren't castling through check # There's no need to check for kings, because they can't threaten check at this spot without our king already being in check ()? # decide between bishops/queens or rooks/queens ()? # for bishops/queens, decide between one diagonal or the other (?(1) (?|\X{7}(?2)?P # pawns (capture diagonally) |(\X{6}|\X{10}|\X{16}(?2)?)N # knights |((?(-1)-)\X{7}(?(-2)(?2)))+[BQ] # bishops or queens |((?(-1)-)\X{8} )+[RQ]) # rooks or queens (only look downward, because left/right are impossible in this context) | (?<=p\PM{8}|p\PM{10} # pawns (capture diagonally) |(?=(?:|(?2)|\X{8}|\X{12})n)\PM{20} # knights |((?<= # bishops/queens or rooks/queens (?!.*\n\n) (?= (?(-4) \X # rooks or queens (only look upward, because left/right are impossible in this context) | (?(-3)(?2)) # bishops or queens ) (?:(?(-4)[rq]|[bq])|-(?-1)) ) \PM{11} ))) ) ) (?=(?5)-(-[Kk]|[Rr])\g{-6}-)--(?=\g{-1}(?10))-?\14 | # bishops, rooks, queens, knights, or kings (?<e>(?7).)? # decide between scanning forward (<e> is unset) or backwards (<e> is captured) (?= (?i: (?| (?(e)|(B|Q)) (?&B) (?(e)(B|Q)) | # bishops or queens (?(e)|(R|Q)) (?&R) (?(e)(R|Q)) | # rooks or queens (?(e)|(N )) (?&N) (?(e)(N )) | # knights (?(e)|(K )) (?&K)? (?(e)(K )) # kings ) ) (?(e)(?<=(?!(?7)).)(?4)|(?7).(?5)\g{-2}) # verify that the piece moved, and optionally captured piece, are of the correct color ) (?(e)(?=(?5)\g{-1})|(?6).(?4)) # verify that the piece moved is the same type and color at its destination in the next turn's board position )(?<m>) | (?(+1)$)(.) # handle the destination/source square that a piece moved to/from (only allow matching one of these per turn) )+\n )+ \k<m> # assert that a move has taken place (?=\n(?14)) # don't allow moving into check \1? # if white moved last, black moves next, and vice-versa """## let regex = try! NSRegularExpression(pattern: pattern, options: .allowCommentsAndWhitespace) let testString = #""" rnbqkbnr pppppppp -------- -------- -------- -------- PPPPPPPP RNBQKBNR rnbqkbnr pppppppp -------- -------- ----P--- -------- PPPP-PPP RNBQKBNR rnbqkbnr pppp-ppp ----p--- -------- ----P--- -------- PPPP-PPP RNBQKBNR rnbqkbnr pppp-ppp ----p--- -------- ---PP--- -------- PPP--PPP RNBQKBNR rnbqkbnr ppp--ppp ----p--- ---p---- ---PP--- -------- PPP--PPP RNBQKBNR rnbqkbnr ppp--ppp ----p--- ---pP--- ---P---- -------- PPP--PPP RNBQKBNR rnbqkbnr pp---ppp ----p--- --ppP--- ---P---- -------- PPP--PPP RNBQKBNR rnbqkbnr pp---ppp ----p--- --ppP--- ---P---- --P----- PP---PPP RNBQKBNR rnbqkbnr pp---ppp ----p--- ---pP--- ---p---- --P----- PP---PPP RNBQKBNR rnbqkbnr pp---ppp ----p--- ---pP--- ---P---- -------- PP---PPP RNBQKBNR rnbqk-nr pp---ppp ----p--- ---pP--- -b-P---- -------- PP---PPP RNBQKBNR rnbqk-nr pp---ppp ----p--- ---pP--- -b-P---- --N----- PP---PPP R-BQKBNR r-bqk-nr pp---ppp --n-p--- ---pP--- -b-P---- --N----- PP---PPP R-BQKBNR r-bqk-nr pp---ppp --n-p--- ---pP--- -b-P---- --N--N-- PP---PPP R-BQKB-R r-bqk--r pp--nppp --n-p--- ---pP--- -b-P---- --N--N-- PP---PPP R-BQKB-R r-bqk--r pp--nppp --n-p--- ---pP--- -b-P---- --NB-N-- PP---PPP R-BQK--R r-bq-rk- pp--nppp --n-p--- ---pP--- -b-P---- --NB-N-- PP---PPP R-BQK--R r-bq-rk- pp--nppB --n-p--- ---pP--- -b-P---- --N--N-- PP---PPP R-BQK--R r-bq-r-- pp--nppk --n-p--- ---pP--- -b-P---- --N--N-- PP---PPP R-BQK--R r-bq-r-- pp--nppk --n-p--- ---pP-N- -b-P---- --N----- PP---PPP R-BQK--R r-bq-r-- pp--npp- --n-p-k- ---pP-N- -b-P---- --N----- PP---PPP R-BQK--R r-bq-r-- pp--npp- --n-p-k- ---pP-N- -b-P---P --N----- PP---PP- R-BQK--R r-bq-r-- pp--npp- ----p-k- ---pP-N- -b-n---P --N----- PP---PP- R-BQK--R r-bq-r-- pp--npp- ----p-k- ---pP-N- -b-n--QP --N----- PP---PP- R-B-K--R r-bq-r-- pp--n-p- ----p-k- ---pPpN- -b-n--QP --N----- PP---PP- R-B-K--R r-bq-r-- pp--n-p- ----p-k- ---pPpNP -b-n--Q- --N----- PP---PP- R-B-K--R r-bq-r-- pp--n-p- ----p--k ---pPpNP -b-n--Q- --N----- PP---PP- R-B-K--R r-bq-r-- pp--n-p- ----N--k ---pPp-P -b-n--Q- --N----- PP---PP- R-B-K--R r-bq-r-- pp--n--- ----N--k ---pPppP -b-n--Q- --N----- PP---PP- R-B-K--R r-bq-r-- pp--n--- ----N-Pk ---pPp-- -b-n--Q- --N----- PP---PP- R-B-K--R WIN BY CHECKMATE """# let stringRange = NSRange(location: 0, length: testString.utf16.count) let matches = regex.matches(in: testString, range: stringRange) var result: [[String]] = [] for match in matches { var groups: [String] = [] for rangeIndex in 1 ..< match.numberOfRanges { let nsRange = match.range(at: rangeIndex) guard !NSEqualRanges(nsRange, NSMakeRange(NSNotFound, 0)) else { continue } let string = (testString as NSString).substring(with: nsRange) groups.append(string) } if !groups.isEmpty { result.append(groups) } } print(result)

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 Swift 5.2, please visit: https://developer.apple.com/documentation/foundation/nsregularexpression