Parser.php 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. <?php
  2. namespace PHPHtmlParser\Selector;
  3. /**
  4. * This is the parser for the selctor.
  5. *
  6. *
  7. */
  8. class Parser implements ParserInterface
  9. {
  10. /**
  11. * Pattern of CSS selectors, modified from 'mootools'
  12. *
  13. * @var string
  14. */
  15. protected $pattern = "/([\w\-:\*>]*)(?:\#([\w\-]+)|\.([\w\-]+))?(?:\[@?(!?[\w\-:]+)(?:([!*^$]?=)[\"']?(.*?)[\"']?)?\])?([\/, ]+)/is";
  16. /**
  17. * Parses the selector string
  18. *
  19. * @param string $selector
  20. */
  21. public function parseSelectorString(string $selector): array
  22. {
  23. $selectors = [];
  24. $matches = [];
  25. preg_match_all($this->pattern, trim($selector).' ', $matches, PREG_SET_ORDER);
  26. // skip tbody
  27. $result = [];
  28. foreach ($matches as $match) {
  29. // default values
  30. $tag = strtolower(trim($match[1]));
  31. $operator = '=';
  32. $key = null;
  33. $value = null;
  34. $noKey = false;
  35. $alterNext = false;
  36. // check for elements that alter the behavior of the next element
  37. if ($tag == '>') {
  38. $alterNext = true;
  39. }
  40. // check for id selector
  41. if ( ! empty($match[2])) {
  42. $key = 'id';
  43. $value = $match[2];
  44. }
  45. // check for class selector
  46. if ( ! empty($match[3])) {
  47. $key = 'class';
  48. $value = $match[3];
  49. }
  50. // and final attribute selector
  51. if ( ! empty($match[4])) {
  52. $key = strtolower($match[4]);
  53. }
  54. if ( ! empty($match[5])) {
  55. $operator = $match[5];
  56. }
  57. if ( ! empty($match[6])) {
  58. $value = $match[6];
  59. }
  60. // check for elements that do not have a specified attribute
  61. if (isset($key[0]) && $key[0] == '!') {
  62. $key = substr($key, 1);
  63. $noKey = true;
  64. }
  65. $result[] = [
  66. 'tag' => $tag,
  67. 'key' => $key,
  68. 'value' => $value,
  69. 'operator' => $operator,
  70. 'noKey' => $noKey,
  71. 'alterNext' => $alterNext,
  72. ];
  73. if (trim($match[7]) == ',') {
  74. $selectors[] = $result;
  75. $result = [];
  76. }
  77. }
  78. // save last results
  79. if (count($result) > 0) {
  80. $selectors[] = $result;
  81. }
  82. return $selectors;
  83. }
  84. }