Skip to main content
7 of 7
Make sample code quoted.
rolfl
  • 97.5k
  • 17
  • 218
  • 418

Regular Expression for parsing PHP annotations containing multiple lines and markup

I am writing a regular expression for parsing PHP annotations in a flexible way. I'd like to accomplish all the goals listed above with one single expression. So I would appreciate any suggestions about the quality of it (in terms of corner cases, performance, best practices and correctness).

PCRE expression:

/[\*\s]*@(?P<name>\w+[\\\w]*?)(?:\s|\()
(?P<value>
  (?:[\/\w\s\"\<\>\_\#\=\-\.\'\{\}:;,\*\(\)\[\]]*[^\R\*\s\/\)])
)?
(?:\s | $|\))/gsxmu

Goals of the regular expression:

  • List all annotations with their values
  • Values can be multi-lined and have markup (html, json or markdown)
  • The initial space + * of each line should be removed from the value
  • Many annotations can be in the same line
  • Annotation names can be namespaced

Sample PHPDoc string:

/**
 * Description
 * 
 * @Tag name name @annotation beee @aaf dsfsd fgdg
 * @Tag name name {"json":"dfsf"}
 * @Tag asdasd <html> #markdown ==markdown== __markdown__
 * - markdown
 * > mark 1
.mark
"string"
'string'
 * @Annotation()
 * @Tag name name @annotation beee @aaf dsfsd fgdg <markdown> #markdown ==markdown==
 * @a() @b("name") @c()
 * @Annotation\Name("var1()", "var2") @n("name()_name")
 * @Annotation(["var1", "var2"], "var3")
 * @Annotation\Filter\Name(["var1", "var2"], "var3", {"var4": "var5"})
 * @Annotation(
 *    ["GET", "POST"]
   ) @Name({"name": "Tomas"})
 * @Tag name name
 */

Expected result:

<?php

array(
  [
      'name' => 'Tag',
      'value' => 'name name'
  ],
  [
      'name' => 'annotation',
      'value' => 'bee'
  ],
  [
      'name' => 'aaf',
      'value' => 'dsfsd fgdg'
  ]
  // ... and so on... (see live example)
);

A live demo can be found here.

itsjavi
  • 137
  • 4