Regular Expressions 101

Save & Share

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
  • Match everything enclosed
    (?:...)
  • Capture everything enclosed
    (...)
  • 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

/
/
ixgms

Test String

Code Generator

Generated Code

# coding=utf8 # the above tag defines encoding for this document and is for Python 2.x compatibility import re regex = r""" (\s+)(?:abstract\s+|final\s+|private\s+|protected\s+|public\s+)?(?:static\s+)?(function)\s+(\w+)\s*(\((?>[^()]+|(?R))*\))|({(?>[^{}]+|(?R))*}) """ test_str = ("<?php declare(strict_types=1);\n\n" "namespace PHPAstVisualizer;\n\n" "use phpDocumentor\\GraphViz\\Edge as GraphEdge;\n" "use phpDocumentor\\GraphViz\\Graph;\n" "use phpDocumentor\\GraphViz\\Node as GraphNode;\n\n" "class Options {\n" " private $options = [\n" " 'graph' => [],\n" " 'node' => ['shape' => 'rect'],\n" " 'edge' => [],\n" " 'childEdge' => ['style' => 'dashed','arrowhead' => 'empty'],\n" " ];\n" " private $name;\n" "}\n\n" " public function __construct(string $name, array $options = []) {\n" " $this->name = $name;\n" " $this->graphOptions = array_merge($this->options, $options);\n" " }\n\n" " public function getName(): string {\n" " return $this->name;\n" " }\n\n" " public function graph(Graph $graph) {\n" " foreach ($this->options['graph'] as $name => $value) {\n" " $graph->{'set' . $name}($value);\n" " }\n" " }\n\n" " public function node(GraphNode $node) {\n" " foreach ($this->options['node'] as $name => $value) {\n" " $node->{'set' . $name}($value);\n" " }\n" " }\n\n" " public function childEdge(GraphEdge $edge) {\n" " $this->edge($edge);\n" " foreach ($this->options['childEdge'] as $name => $value) {\n" " $edge->{'set' . $name}($value);\n" " }\n" " }\n\n" " public function edge(GraphEdge $edge) {\n" " foreach ($this->options['edge'] as $name => $value) {\n" " $edge->{'set' . $name}($value);\n" " }\n" " }\n" "}\n" " /**\n" " * PHP file with an autoload function which will be included into the\n" " * sandbox of the InstantSVC CodeAnalyzer\n" " * @var string\n" " */\n" " protected $autoloadFile = '';\n\n" " /**\n" " * Sets the output driver and initializes\n" " * @param CallgraphDriver $driver output driver to use\n" " * @return PHPCallGraph\n" " */\n" " public function __construct(CallgraphDriver $driver = null) {\n" " if ($driver != null) {\n" " $this->driver = $driver;\n" " } else {\n" " $this->driver = new TextDriver();\n" " }\n" " $functions = get_defined_functions();\n" " $this->internalFunctions = $functions['internal'];\n" " // List of PHP keywords which could be followed by an opening parenthis\n" " // taken from PHP Manual (http://www.php.net/reserved_keywords)\n" " $this->internalKeywords = array(\n" " 'array', 'declare', 'die', 'echo', 'elseif', 'empty', 'eval',\n" " 'exit', 'for', 'foreach', 'global', 'if', 'include', 'include_once',\n" " 'isset', 'list', 'print', 'require', 'require_once', 'return',\n" " 'switch', 'unset', 'while', 'catch', 'or', 'and', 'xor', 'new Exception');\n" " $this->constants = array_keys(get_defined_constants());\n\n" " //TODO: provide setter for this\n" " //$this->ignoreList = array('PHPCallGraph::setDriver', 'PHPCallGraph::__construct', 'PHPCallGraph::setShowExternalCalls', 'PHPCallGraph::setShowInternalFunctions', 'PHPCallGraph::save', 'PHPCallGraph::__toString');\n" " }\n\n" " public function setDriver(CallgraphDriver $driver = null) {\n" " if ($driver != null) {\n" " $this->driver = $driver;\n" " }\n" " }\n\n" " /**\n" " * Enable or disable printing of debug information\n" " * @param boolean $enabled\n" " */\n" " public function setDebug($enabled = true) {\n" " $this->debug = $enabled;\n" " }\n\n" " protected function debug($string) {\n" " if ($this->debug) {\n" " print \"||PHPCallGraph| \".$string.\"\\n\";\n" " }\n" " }\n\n" " protected function info($string) {\n" " if ($this->showInfo) {\n" " print \"||PHPCallGraph| \".$string.\"\\n\";\n" " }\n" " }\n\n" " protected function warning($string) {\n" " if ($this->showWarnings) {\n" " print \"||PHPCallGraph* *WARNING* \".$string.\"\\n\";\n" " }\n" " }\n\n\n" " /**\n" " * Sets a PHP file with an autoload function which will be included into\n" " * the sandbox of the InstantSVC CodeAnalyzer\n" " * @param string $filename Name of a PHP file with an autoload function\n" " * @return boolean success\n" " */\n" " public function setAutoloadFile($filename) {\n" " $returnValue = false;\n" " if (!empty($filename) and is_file($filename) and is_readable($filename)) {\n" " $this->autoloadFile = $filename;\n" " $returnValue = true;\n" " } else {\n" " //TODO: throw exception\n" " }\n" " return $returnValue;\n" " }\n\n" " public function setShowExternalCalls($boolean = true) {\n" " $this->showExternalCalls = $boolean;\n" " }\n\n" " public function setShowInternalFunctions($boolean = true) {\n" " $this->showInternalFunctions = $boolean;\n" " }\n\n" " public function collectFileNames(array $filesOrDirs, $recursive = false) {\n" " $files = array();\n" " foreach ($filesOrDirs as $fileOrDir) {\n" " if (is_file($fileOrDir)) {\n" " $files[] = $fileOrDir;\n" " } elseif (is_dir($fileOrDir)) {\n" " $globbed = glob(\"$fileOrDir/*\");\n" " if ($recursive) {\n" " $files = array_merge($files, $this->collectFileNames($globbed, true));\n" " } else {\n" " foreach($globbed as $path) {\n" " if (is_file($path)) {\n" " $files[] = $path;\n" " }\n" " }\n" " }\n" " }\n" " }\n" " return $files;\n" " }\n\n" " public function parse(array $filesOrDirs, $recursive = false) {\n" " $files = $this->collectFileNames($filesOrDirs, $recursive);\n" " if ($this->debug) {\n" " var_dump($files);\n" " }\n\n" " $ca = new iscCodeAnalyzer(null);\n" " $ca->setDebug($this->debug);\n" " $ca->setAutoloadFile($this->autoloadFile);\n" " $ca->inspectFiles($files);\n" " $this->codeSummary = $ca->getCodeSummary();\n" " $this->analyseCodeSummary();\n" " }\n\n" " public function parseFile($file) {\n" " $ca = new iscCodeAnalyzer(null);\n" " $ca->setDebug($this->debug);\n" " $ca->setAutoloadFile($this->autoloadFile);\n" " $ca->inspectFiles(array($file));\n" " $this->codeSummary = $ca->getCodeSummary();\n" " $this->analyseCodeSummary();\n" " }\n\n" " public function parseDir($dir = '.') {\n" " $ca = new iscCodeAnalyzer($dir);\n" " $ca->setDebug($this->debug);\n" " $ca->setAutoloadFile($this->autoloadFile);\n" " $ca->collect();\n" " $this->codeSummary = $ca->getCodeSummary();\n" " $this->analyseCodeSummary();\n" " }\n\n" " public function analyseCodeSummary() {\n" " $this->buildLookupTables();\n\n" " //TODO: analyze code in the global scope\n" " // currently a workarround is to manually wrap such code\n" " // in a dummy function called dummyFunctionForFile_filename_php()\n\n" " // analyze functions\n" " if (!empty($this->codeSummary['functions'])) {\n" " foreach ($this->codeSummary['functions'] as $functionName => $function) {\n" " $this->parseMethodBody(\n" " '-',\n" " $functionName,\n" " array(),\n" " array(),\n" " $function['file'],\n" " $function['startLine'],\n" " $function['endLine']\n" " );\n" " }\n" " }\n\n" " // analyze classes\n" " if (!empty($this->codeSummary['classes'])) {\n" " foreach ($this->codeSummary['classes'] as $className => $class) {\n" " /*\n" " echo $className, \"\\n\";\n" " var_export($class);\n" " echo \"\\n\\n\";\n" " //*/\n" " if (!empty($class['methods'])) {\n" " $propertyNames = array_keys($class['properties']);\n" " $methodNames = array_keys($class['methods']);\n" " //var_export($propertyNames);\n" " //var_export($methodNames);\n" " foreach ($class['methods'] as $methodName => $method) {\n" " $this->parseMethodBody(\n" " $className,\n" " $methodName,\n" " $propertyNames,\n" " $methodNames,\n" " $class['file'],\n" " $method['startLine'],\n" " $method['endLine']\n" " );\n" " }\n" " }\n" " }\n" " }\n" " }\n\n" " protected function buildLookupTables() {\n" " if (!empty($this->codeSummary['classes'])) {\n" " foreach ($this->codeSummary['classes'] as $className => $class) {\n" " //currently unused\n" " /*\n" " if (!empty($class['properties'])) {\n" " foreach ($class['properties'] as $propertyName => $property) {\n" " $this->propertyLookupTable[$propertyName][] = $className;\n" " }\n" " }\n" " //*/\n" " if (!empty($class['methods'])) {\n" " foreach ($class['methods'] as $methodName => $method) {\n" " $this->methodLookupTable[$methodName][] = $className;\n" " }\n" " }\n" " }\n" " }\n" " }\n\n" " /**\n" " * @param string $className\n" " * @param string $methodName\n" " * @param array $propertyNames\n" " * @param array $methodNames\n" " * @param string $file\n" " * @param integer $startLine\n" " * @param integer $endLine\n" " */\n" " public function parseMethodBody(\n" " $className,\n" " $methodName,\n" " Array $propertyNames,\n" " Array $methodNames,\n" " $file,\n" " $startLine,\n" " $endLine\n" " ) {\n" " if ($className == '-') { // we are analyzing a function not a method\n" " if (substr($methodName, 0, strlen('dummyFunctionForFile_')) == 'dummyFunctionForFile_') {\n" " // the function has been introduced manually to encapsulate code in the global scope\n" " $callerName = str_replace('_', '.', substr($methodName, strlen('dummyFunctionForFile_'))) . '(File)';\n" " } else {\n" " $callerName = $methodName . $this->generateParametersForSignature($this->codeSummary['functions'][$methodName]['params']);\n" " }\n" " } else {\n" " //TODO: visibilities\n" " $callerName = $className . '::' . $methodName . $this->generateParametersForSignature($this->codeSummary['classes'][$className]['methods'][$methodName]['params']);\n" " }\n\n" " $callerNameWithoutParameterList = substr($callerName, 0, strpos($callerName, '('));\n" " \n" " if (!in_array($callerNameWithoutParameterList, $this->ignoreList)) {\n" " $this->debug('phpCallGraph: analyzing ' . $callerName);\n" " $offset = $startLine - 1;\n" " $length = $endLine - $startLine + 1;\n\n" " // obtain source code\n" " $memberCode = implode('', array_slice(file($file), $offset, $length));\n" " $memberCode = \"<?php\\nclass $className {\\n\" . $memberCode . \"}\\n?>\\n\";\n" " //echo $memberCode;\n\n" " $this->debug(\"= Analyzing $callerName =\");\n" " $this->info(\" defined in $file on line $offset\");\n" " $this->driver->startFunction($offset, $file, $callerName, $memberCode);\n\n" " $insideDoubleQuotedString = false;\n" " $lineNumber = $offset - 1;\n" " $blocksStarted = 0;\n" " // parse source code\n" " $tokens = token_get_all($memberCode);\n" " /*\n" " if ($methodName == '__construct') {\n" " print_r($tokens);\n" " }\n" " //*/\n\n" " //TODO: implement a higher level API for working with PHP parser tokens (e.g. TokenIterator)\n" " foreach ($tokens as $i => $token) {\n" " //TODO: obtain method signature directly from the source file\n" " if (is_array($token)) {\n" " $lineNumber+= substr_count($token[1], \"\\n\");\n" " }\n\n" " /*\n" " if (count($token) == 3) {\n" " echo \"\\t\", token_name($token[0]), \"\\n\";\n" " echo \"\\t\\t\", $token[1], \"\\n\";\n" " } else {\n" " echo \"\\t\", $token[0], \"\\n\";\n" " }\n" " //*/\n\n" " // skip call analysis for the method signature\n" " if ($blocksStarted < 2) {\n" " // method body not yet started\n" " if ($token[0] == '{') {\n" " ++$blocksStarted;\n" " }\n" " continue;\n" " }\n\n" " if (!$insideDoubleQuotedString and $token == '\"') {\n" " $insideDoubleQuotedString = true;\n" " } elseif ($insideDoubleQuotedString and $token == '\"') {\n" " $insideDoubleQuotedString = false;\n" " } elseif (!$insideDoubleQuotedString and $token != '\"') {\n" " if ($token[0] == T_STRING\n" " //and ($token[1] != $className or $tokens[$i - 2][0] == T_NEW )\n" " //and $token[1] != $methodName\n" " ) {\n" " if (\n" " !in_array($token[1], $propertyNames) //TODO: property name equals name of a function or method\n" " and !in_array($token[1], $this->constants) //TODO: constant name equals name of a function or method\n" " and $token[1] != 'true'\n" " and $token[1] != 'false'\n" " and $token[1] != 'null'\n" " ) {\n" " $previousPreviousPreviousToken = $tokens[ $i - 3 ];\n" " $previousPreviousToken = $tokens[ $i - 2 ];\n" " $previousToken = $tokens[ $i - 1 ];\n" " $nextToken = $tokens[ $i + 1 ];\n" " $tokenAfterNext = $tokens[ $i + 2 ];\n\n" " $this->info($this->getTokenValues($tokens, $i));\n\n\n" " if ($nextToken[0] == T_DOUBLE_COLON) {\n" " // beginning of a call to a static method\n" " //nop\n" " continue;\n" " } elseif (\n" " (\n" " $tokens[ $i - 4][0] == T_CATCH\n" " and $previousPreviousPreviousToken[0] == T_WHITESPACE\n" " and $previousPreviousToken == '('\n" " and $previousToken[0] == T_WHITESPACE\n" " )\n" " or\n" " (\n" " $previousPreviousPreviousToken[0] == T_CATCH\n" " and $previousPreviousToken[0] == T_WHITESPACE\n" " and $previousToken == '('\n" " )\n" " or\n" " (\n" " $previousPreviousToken[0] == T_CATCH\n" " and $previousToken == '('\n" " )\n" " ){\n" " // catch block\n" " continue;\n" " } elseif ($previousPreviousToken[0] == T_NEW){\n" " $this->debug('Found object creation with new operator');\n" " if (!$this->showExternalCalls) {\n" " continue;\n" " }\n" " $calleeClass = $token[1];\n" " if (isset($this->codeSummary['classes'][$calleeClass])) {\n" " // find constructor method\n" " if (isset($this->codeSummary['classes'][$calleeClass]['methods']['__construct'])) {\n" " $calleeName = \"$calleeClass::__construct\"\n" " . $this->generateParametersForSignature($this->codeSummary['classes'][$calleeClass]['methods']['__construct']['params']);\n" " } elseif (isset($this->codeSummary['classes'][$calleeClass]['methods'][$calleeClass])) {\n" " $calleeName = \"$calleeClass::$calleeClass\"\n" " . $this->generateParametersForSignature($this->codeSummary['classes'][$calleeClass]['methods'][$calleeClass]['params']);\n" " } else {\n" " $calleeName = \"$calleeClass::__construct()\";\n" " }\n" " $calleeFile = $this->codeSummary['classes'][$calleeClass]['file'];\n" " } else {\n" " // TODO: decide how this case should be handled (could be a PEAR class or a class of a PHP extension, e.g. GTK)\n" " //if ($this->showInternalFunctions)\n" " $calleeName = \"$calleeClass::__construct()\"; // TODO: it could also be $calleeClass::$calleeClass() implemented in PHP4-style, however if we don't have the code, we can't now\n" " $calleeFile = '';\n" " }\n\n" " $this->info($this->getTokenValues($tokens, $i));\n" " $this->recordVariableAsType($calleeClass, $tokens[$i-6][1]);\n" " } elseif (\n" " (\n" " isset($previousPreviousToken[1]) and $previousPreviousToken[1] == '$this'\n" " and $previousToken[0] == T_OBJECT_OPERATOR\n" " and in_array($token[1], $methodNames)\n" " )\n" " or\n" " (\n" " isset($previousPreviousToken[1]) and $previousPreviousToken[1] == 'self'\n" " and $previousToken[0] == T_DOUBLE_COLON\n" " and in_array($token[1], $methodNames)\n" " )\n" " ){\n" " $this->info('internal method call ($this-> and self:: and $className::)');\n" " $calleeName = \"$className::{$token[1]}\" . $this->generateParametersForSignature($this->codeSummary['classes'][$className]['methods'][$token[1]]['params']);\n" " $calleeFile = $file;\n" " } elseif ($previousToken[0] == T_OBJECT_OPERATOR) {\n" " $this->debug('External method call or property access'); \n" " //TODO: what if a object holds another instance of its class\n" " if (!$this->showExternalCalls) {\n" " continue;\n" " }\n" " if ($nextToken == '(' or ($nextToken[0] == T_WHITESPACE and $tokenAfterNext == '(')) {\n" " $calleeName = $token[1];\n" " $this->debug(\"Calling for $calleeName\");\n\n" " $variable = $tokens[$i-2][1];\n" " $this->debug(\"Variable = $variable\");\n" " $calleeClass = $this->lookupTypeForVariable($variable);\n" " $this->debug('found as ' . $calleeClass);\n" " if ($calleeClass) {\n" " $calleeParams = $this->generateParametersForSignature(\n" " $this->codeSummary['classes'][$calleeClass]['methods'][$calleeName]['params']\n" " );\n" " $calleeFile = $this->codeSummary['classes'][$calleeClass]['file'];\n" " } else {\n" " if (\n" " isset($this->methodLookupTable[$calleeName])\n" " and count($this->methodLookupTable[$calleeName]) == 1\n" " ) {\n" " // there is only one class having a method with this name\n" " // SMELL: but if the user only registers part of a system the only one hit \n" " // is not necessarily valid.\n" " $calleeClass = $this->methodLookupTable[$calleeName][0];\n" " if (isset($this->codeSummary['classes'][$calleeClass])) {\n" " $calleeParams = $this->generateParametersForSignature(\n" " $this->codeSummary['classes'][$calleeClass]['methods'][$calleeName]['params']\n" " );\n" " $calleeFile = $this->codeSummary['classes'][$calleeClass]['file'];\n\n" " $this->info(\"RECORDING CLASS OF $previousPreviousToken[1] VARIABLE to be $calleeClass\\n\");\n" " $this->info($this->getTokenValues($tokens, $i));\n\n" " } else {\n" " $this-warning(\"calleeClass is unset\");\n" " $calleeParams = null;\n" " $calleeFile = null;\n" " }\n" " } else {\n" " $numEntries = count($this->methodLookupTable[$calleeName]);\n" " if ($numEntries == 0) {\n" " $this->warning(\"method $calleeName was called, but I have no record for that\");\n" " } else {\n" " $this->warning(\"I have $numEntries for $calleeName!\");\n" " }\n\n" " $this->info($this->getTokenValues($tokens, $i));\n\n" " $calleeClass = '';\n" " $calleeParams = '()';\n" " $calleeFile = '';\n" " }\n" " }\n" " $calleeName = \"$calleeClass::$calleeName$calleeParams\";\n" " } else {\n" " $this->info(\"Property access\");\n" " continue;\n" " }\n" " } elseif ($previousToken[0] == T_DOUBLE_COLON){\n" " $this->debug(\"static external method call\");\n" " if (!$this->showExternalCalls) {\n" " continue;\n" " }\n" " if ($nextToken != '(' and !($nextToken[0] == T_WHITESPACE and $tokenAfterNext == '(')) {\n" " // constant access\n" " continue;\n" " }\n" " $calleeClass = $previousPreviousToken[1];\n" " $calleeMethod = $token[1];\n" " $calleeFile = '';\n" " $calleeParams = '()';\n" " // parent::\n" " if ($calleeClass == 'parent' and !empty($this->codeSummary['classes'][$className]['parentClass'])) {\n" " $calleeClass = $this->codeSummary['classes'][$className]['parentClass'];\n" " }\n" " if (isset($this->codeSummary['classes'][$calleeClass])) {\n" " $calleeFile = $this->codeSummary['classes'][$calleeClass]['file'];\n" " if (isset($this->codeSummary['classes'][$calleeClass]['methods'][$calleeMethod]['params'])) {\n" " $calleeParams = $this->generateParametersForSignature($this->codeSummary['classes'][$calleeClass]['methods'][$calleeMethod]['params']);\n" " }\n" " }\n" " $calleeName = \"$calleeClass::$calleeMethod$calleeParams\";\n" " //TODO: handle self::myMethod(); $className::myMethod(); here => abolish internal method call case\n" " } else {\n\n" " $calledFunction = $token[1];\n" " $calleeFile = '';\n" " $calleeParams = '()';\n" " \n" " $this->info(\"Function call: \".$calledFunction);\n\n" " if (in_array($calledFunction, $this->internalFunctions)) {\n" " if (!$this->showInternalFunctions) {\n" " continue;\n" " }\n" " } else {\n" " if (!$this->showExternalCalls) {\n" " continue;\n" " }\n" " if (isset($this->codeSummary['functions'][$calledFunction])) {\n" " $calleeFile = $this->codeSummary['functions'][$calledFunction]['file'];\n" " if (isset($this->codeSummary['functions'][$calledFunction]['params'])) {\n" " $calleeParams = $this->generateParametersForSignature($this->codeSummary['functions'][$calledFunction]['params']);\n" " }\n" " }\n" " }\n" " $calleeName = $calledFunction . $calleeParams;\n" " }\n" " $this->debug(\"---> $calleeName called from line $lineNumber and defined in $calleeFile\");\n" " $this->driver->addCall($lineNumber, $calleeFile, $calleeName);\n" " }\n" " }\n" " } else {\n" " //TODO: parse calls inside double quoted strings\n" " $this->info(' ignoring code inside \"\"');\n" " }\n" " }\n" " $this->debug('== endFunction ==');\n" " $this->driver->endFunction();\n" " }\n" " }\n" "}\n\n" " public function generateParametersForSignature($parameters) {\n" " $result = '(';\n" " if (!empty($parameters)) {\n" " foreach($parameters as $parameterName => $parameter) {\n" " if ($parameter['byReference']) {\n" " $result.= '&';\n" " }\n" " $result.= '$' . $parameterName . ', ';\n" " }\n" " $result = substr($result, 0, -2);\n" " }\n" " $result.= ')';\n" " return $result;\n" " }\n" "}\n" " public function __toString() {\n" " return $this->driver->__toString();\n" " }\n\n" " public function save($file) {\n" " return file_put_contents($file, $this->__toString());\n" " }\n\n" " \n" " protected function getTokenValues($tokens, $i) {\n" " $width = 10;\n" " $pad = ' ';\n" " $out = \"\\n\";\n" " $start = -5;\n" " $end = 4;\n" " $headerLine = '';\n" " $rowLine = '';\n" " $tokenLine = '';\n" " for ($j = $start; $j <= $end; $j++) {\n" " $n = ($i + $j);\n" " $currentToken = $tokens[$n];\n" " $tokenType = '';\n" " $cell = '';\n" " $header = '';\n" " if (is_array($currentToken)) {\n" " $mainValue = $currentToken[1];\n" " $mainValue = str_replace(\"\\n\", '\\n', $mainValue);\n" " $mainValue = str_replace(\"\\t\", '\\t', $mainValue);\n" " if ($mainVlaue = '') {\n" " $mainValue = 'nil';\n" " } \n" " $cell = $mainValue;\n" " $tokenType = token_name($currentToken[0]);\n" " } else {\n" " $cell = '\"'.$currentToken.'\"';\n" " }\n" " $cell = $cell;\n" " $cell = str_pad($cell, $width, $pad);\n" " $tokenType = str_pad(substr($tokenType,0,$width), $width, $pad);\n" " $header = '['.$j.']';\n" " $header = str_pad($header, $width, $pad);\n\n" " $headerLine .= $header.' ';\n" " $rowLine .= $cell.' ';\n" " $tokenLine .= $tokenType.' ';\n" " }\n" " $out .= $headerLine.\"\\n\";\n" " $out .= $rowLine.\"\\n\";\n" " $out .= $tokenLine.\"\\n\";\n" " return $out;\n" " }\n\n" " protected $variableTypes = array();\n" " protected function recordVariableAsType($class, $variable) {\n" " $this->debug(\"RECORDING $variable AS TYPE $class\");\n" " $this->variableTypes[$variable] = $class;\n" " }\n\n\n" " /**\n" " * Returns a recorded type for a given variable, unless the variable is named '$self'\n" " * in which case returns the class name.\n" " * If no match is found returns null.\n" " */\n" " protected function lookupTypeForVariable($variable) {\n" " $recordedType = $this->variableTypes[$variable];\n" " if ($recordedType) {\n" " $type = $recordedType;\n" " } else {\n" " $this->warning(\"No recorded type for $variable\");\n" " $type = null;\n" " }\n" " $this->info('LOOKUP FOR '.$variable.' returns '.$type);\n" " return $type;\n" " }\n" "}\n" "?>\n" "<?php\n" "/**\n" " * Implementation of a call graph generation strategy wich renders a graph with\n" " * dot.\n" " *\n" " * PHP version 5\n" " *\n" " * This file is part of phpCallGraph.\n" " *\n" " * PHPCallGraph is free software; you can redistribute it and/or modify\n" " * it under the terms of the GNU General Public License as published by\n" " * the Free Software Foundation; either version 3 of the License, or\n" " * (at your option) any later version.\n" " *\n" " * PHPCallGraph is distributed in the hope that it will be useful,\n" " * but WITHOUT ANY WARRANTY; without even the implied warranty of\n" " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" " * GNU General Public License for more details.\n" " *\n" " * You should have received a copy of the GNU General Public License\n" " * along with this program. If not, see <http://www.gnu.org/licenses/>.\n" " *\n" " * @package PHPCallGraph\n" " * @author Falko Menge <fakko at users dot sourceforge dot net>\n" " * @copyright 2007-2009 Falko Menge\n" " * @license http://www.gnu.org/licenses/gpl.txt GNU General Public License\n" " */\n\n" "// reduce warnings because of PEAR dependency\n" "error_reporting(E_ALL ^ E_NOTICE);\n\n" "require_once 'CallgraphDriver.php';\n" "require_once 'Image/GraphViz.php';\n\n" "/**\n" " * Implementation of a call graph generation strategy wich renders a graph with\n" " * dot.\n" " */\n" "class GraphVizDriver implements CallgraphDriver {\n\n" " protected $outputFormat;\n" " protected $dotCommand;\n" " protected $useColor = true;\n" " protected $graph;\n" " protected $currentCaller = '';\n" " protected $internalFunctions;\n" "}\n" " /**\n" " * @return CallgraphDriver\n" " */\n" " public function __construct($outputFormat = 'png', $dotCommand = 'dot') {\n" " $this->initializeNewGraph();\n" " $this->setDotCommand($dotCommand);\n" " $this->setOutputFormat($outputFormat);\n" " $functions = get_defined_functions();\n" " $this->internalFunctions = $functions['internal'];\n" " \n" " }\n\n" " /**\n" " * @return void\n" " */\n" " public function reset() {\n" " $this->initializeNewGraph();\n" " }\n\n" " /**\n" " * @return void\n" " */\n" " protected function initializeNewGraph() {\n" " $this->graph = new Image_GraphViz(\n" " true,\n" " array(\n" " 'fontname' => 'Verdana',\n" " 'fontsize' => 12.0,\n" " //'fontcolor' => 'gray5',\n" " 'rankdir' => 'LR', // left-to-right\n" " )\n" " );\n" " $this->graph->dotCommand = $this->dotCommand;\n" " }\n\n" " /**\n" " * Sets path to GraphViz/dot command\n" " * @param string $dotCommand Path to GraphViz/dot command\n" " * @return void\n" " */\n" " public function setDotCommand($dotCommand = 'dot') {\n" " $this->dotCommand = $dotCommand;\n" " $this->graph->dotCommand = $dotCommand;\n" " }\n\n" " /**\n" " * Sets output format\n" " * @param string $outputFormat One of the output formats supported by GraphViz/dot\n" " * @return void\n" " */\n" " public function setOutputFormat($outputFormat = 'png') {\n" " $this->outputFormat = $outputFormat;\n" " }\n\n" " /**\n" " * Enables or disables the use of color\n" " * @param boolean $boolean True if color should be used\n" " * @return void\n" " */\n" " public function setUseColor($boolean = true) {\n" " $this->useColor = $boolean;\n" " }\n\n" " /**\n" " * @param integer $line\n" " * @param string $file\n" " * @param string $name\n" " * @return void\n" " */\n" " public function startFunction($line, $file, $name, $memberCode) {\n" " $this->addNode($name);\n" " $this->currentCaller = $name;\n" " }\n\n" " /**\n" " * @param integer $line\n" " * @param string $file\n" " * @param string $name\n" " * @return void\n" " */\n" " public function addCall($line, $file, $name) {\n" " $this->addNode($name);\n" " $this->graph->addEdge(array($this->currentCaller => $name));\n" " }\n\n" " /**\n" " * @return void\n" " */\n" " protected function addNode($name) {\n" " $nameParts = explode('::', $name);\n" " $cluster = 'default';\n" " $label = $name;\n" " $color = 'lavender'; //lightblue2, lightsteelblue2, azure2, slategray2\n" " if (count($nameParts) == 2) { // method call\n" " if (empty($nameParts[0])) {\n" " $cluster = 'class is unknown';\n" " } else {\n" " $cluster = $nameParts[0];\n" " }\n" " // obtain method name\n" " $label = $nameParts[1];\n" " }\n" " // remove parameter list\n" " $label = substr($label, 0, strpos($label, '('));\n\n" " if (count($nameParts) == 1) { // function call\n" " if (in_array($label, $this->internalFunctions)) { // call to internal function\n" " $cluster = 'internal PHP functions';\n" " }\n" " }\n" " $this->graph->addNode(\n" " $name,\n" " array(\n" " 'fontname' => 'Verdana',\n" " 'fontsize' => 12.0,\n" " //'fontcolor' => 'gray5',\n" " 'label' => $label,\n" " //'style' => 'rounded' . ($this->useColor ? ',filled' : ''), // produces errors in rendering\n" " 'style' => ($this->useColor ? 'filled' : 'rounded'),\n" " 'color' => ($this->useColor ? $color : 'black'),\n" " 'shape' => ($this->useColor ? 'ellipse' : 'rectangle'),\n" " ),\n" " $cluster\n" " );\n" " //*\n" " $this->graph->addCluster(\n" " $cluster,\n" " $cluster,\n" " array(\n" "// 'style' => ($this->useColor ? 'filled' : ''),\n" " 'color' => 'gray20',\n" "// 'bgcolor' => '',\n" " )\n" " );\n" " //*/\n" " }\n\n" " /**\n" " * @return void\n" " */\n" " public function endFunction() {\n" " }\n\n" " /**\n" " * @return string\n" " */\n" " public function __toString() {\n" " return $this->graph->fetch($this->outputFormat);\n" " }\n" "}\n" "?>\n") matches = re.finditer(regex, test_str, re.IGNORECASE | re.VERBOSE | re.MULTILINE | re.DOTALL) for matchNum, match in enumerate(matches, start=1): print ("Match {matchNum} was found at {start}-{end}: {match}".format(matchNum = matchNum, start = match.start(), end = match.end(), match = match.group())) for groupNum in range(0, len(match.groups())): groupNum = groupNum + 1 print ("Group {groupNum} found at {start}-{end}: {group}".format(groupNum = groupNum, start = match.start(groupNum), end = match.end(groupNum), group = match.group(groupNum))) # Note: for Python 2.7 compatibility, use ur"" to prefix the regex and u"" to prefix the test string and substitution.

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 Python, please visit: https://docs.python.org/3/library/re.html