$re = '/(?:(?<=^\n)|(?<=\A))
(?<table>
(?<table_caption>(?&t_caption))? # maybe some caption at the top?
(?<table_headers>
(?<table_header> # Table header
(?<table_header_sep_top>(?&t_th_sep))? # Possible top separator line
(?<table_header1> # First header row
[^\n]+\n
)
(?<table_header_sep>(?&t_th_sep)) # a separator
(?<table_header2> # and possibly a second row of header
[^\n]+\n
(?<table_header_sep>(?&t_th_sep))
)?
)
)
(?<table_rows> # Multiple table rows
(?<table_row>(?&t_row))*
)
(?<table_bottom_sep>(?&t_th_sep))? # Possibly ended by a separator line
(?<table_caption>(?&t_caption))? # and maybe with some caption at the bottom
(?=\n|\Z)
)
(?(DEFINE)
(?<t_th_sep>
[\+\-\|](?:[\: ]*\-+[\: ]*[\+\-\|]?)+\n
)
(?<t_row>
[ ]{0,3}
(?!(?&t_th_sep)|(?&t_caption))
(?:
(?<tr_start_mark>[\|\:]+)?
(?<tr_col_content>[^\|\:\n]+)
(?:
(?:[\|\:]{0,2}[ ]*(?=\n))
|
[\|\:]{1,2}
)
)+
(?:
(?:\n(?=(?&t_th_sep)))
|
(?:\n(?=(?&t_caption)))
|
\n
)
)
(?<t_caption>
[ ]{0,3}
\[[^\]]+\]
[ ]*
\n
)
)/mxJ';
$str = '| | Grouping ||
+---------------+---------------------------------+
| First Header | Second Header | Third Header |
+---------------+-----------------+---------------+
| Content | *Long Cell* ||
: continued : ::
: content : ::
| Content | **Cell** | Cell |
: continued : : :
: content : : :
| New section | More | Data |
| And more | And more ||
[Prototype table]
Header 1 | Header 2
--------- | ---------
Cell 1 | Cell 2
Cell 3 | Cell 4
With leading pipes:
| Header 1 | Header 2
| --------- | ---------
| Cell 1 | Cell 2
| Cell 3 | Cell 4
With tailing pipes:
Header 1 | Header 2 |
--------- | --------- |
Cell 1 | Cell 2 |
Cell 3 | Cell 4 |
With leading and tailing pipes:
| Header 1 | Header 2 |
| --------- | --------- |
| Cell 1 | Cell 2 |
| Cell 3 | Cell 4 |
* * *
# One-column one-row table
With leading pipes:
| Header
| -------
| Cell
With tailing pipes:
Header |
------- |
Cell |
With leading and tailing pipes:
| Header |
| ------- |
| Cell |
* * *
Table alignement:
| Default | Right | Center | Left |
| --------- |:--------- |:---------:| ---------:|
| Long Cell | Long Cell | Long Cell | Long Cell |
| Cell | Cell | Cell | Cell |
Table alignement (alternate spacing):
| Default | Right | Center | Left |
| --------- | :-------- | :-------: | --------: |
| Long Cell | Long Cell | Long Cell | Long Cell |
| Cell | Cell | Cell | Cell |
* * *
# Empty cells
| Header 1 | Header 2 |
| --------- | --------- |
| A | B |
| C | |
Header 1 | Header 2
--------- | ---------
A | B
| D
* * *
# Missing tailing pipe
Header 1 | Header 2
--------- | --------- |
Cell | Cell |
Cell | Cell |
Header 1 | Header 2 |
--------- | ---------
Cell | Cell |
Cell | Cell |
Header 1 | Header 2 |
--------- | --------- |
Cell | Cell
Cell | Cell |
Header 1 | Header 2 |
--------- | --------- |
Cell | Cell |
Cell | Cell
* * *
# Too many pipes in rows
| Header 1 | Header 2 |
| ---------
| Cell | Cell | Extra cell? |
| Cell | Cell | Extra cell? |
';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
// Print the entire match result
var_dump($matches);
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 PHP, please visit: http://php.net/manual/en/ref.pcre.php