3v4l.org

run code in 500+ PHP versions simultaneously
<?php $HTML = <<< HTML some data from <span class="positive">blahblah test</span> was not <span class="positive">statistically <span class="positive">valid</span></span> <span class="positive">not statistically valid</span> HTML; $listOfNegatives = ['not statistically valid', 'blahblah test']; /** * Extract all words and their corresponsing positions * @param [string] $HTML * @return [array] $HTMLWords */ function extractWords($HTML) { $HTMLWords = []; preg_match_all("~\b(?<![</])\w+\b(?![^<>]+>)~", $HTML, $words, PREG_OFFSET_CAPTURE); foreach ($words[0] as $word) { $HTMLWords[$word[1]] = $word[0]; } return $HTMLWords; } /** * Check if any of our defined list values can be found in an ordered-array of exctracted words * @param [array] $HTMLWords * @param [array] $listOfNegatives * @return [array] $subString */ function checkNegativesExistence($HTMLWords, $listOfNegatives) { $counter = 0; $previousWordOffset = null; $subStrings = []; foreach ($listOfNegatives as $i => $string) { $stringWords = explode(" ", $string); $wordIndex = 0; foreach ($HTMLWords as $offset => $HTMLWord) { if ($wordIndex > count($stringWords) - 1) { $wordIndex = 0; $counter++; } if ($stringWords[$wordIndex] == $HTMLWord) { $subStrings[$counter][] = [$HTMLWord, $offset, $previousWordOffset]; $wordIndex++; } elseif (isset($subStrings[$counter]) && count($subStrings[$counter]) > 0) { unset($subStrings[$counter]); $wordIndex = 0; } $previousWordOffset = $offset + strlen($HTMLWord); } $counter++; } return $subStrings; } /** * Substitute newly matched strings with negative HTML wrapper * @param [array] $subStrings * @param [string] $HTML * @return [string] $HTML */ function negativeHighlight($subStrings, $HTML) { $offset = 0; $HTMLLength = strlen($HTML); foreach ($subStrings as $key => $value) { $arrayOfWords = []; foreach ($value as $word) { $arrayOfWords[] = $word[0]; if (current($value) == $value[0]) { $start = substr($HTML, $word[1], strlen($word[0])) == $word[0] ? $word[2] : $word[2] + $offset; } if (current($value) == end($value)) { $defaultLength = $word[1] + strlen($word[0]) - $start; $length = substr($HTML, $word[1], strlen($word[0])) === $word[0] ? $defaultLength : $defaultLength + $offset; } } $string = implode(" ", $arrayOfWords); $HTML = substr_replace($HTML, "<span class=\"negative\">{$string}</span>", $start, $length); if ($HTMLLength > strlen($HTML)) { $offset = -($HTMLLength - strlen($HTML)); } elseif ($HTMLLength < strlen($HTML)) { $offset = strlen($HTML) - $HTMLLength; } } return $HTML; } $newHTML = negativeHighlight(checkNegativesExistence(extractWords($HTML), $listOfNegatives), $HTML); echo preg_replace_callback("~(<span[^>]+>([^<]*+<(?!/)(?:([a-zA-Z0-9]++)[^>]*>[^<]*</\3>|(?2)))*[^<]*</span>|(?'single'</[^<>]+>|<[^<>]+>))~", function ($match) { if (isset($match['single'])) { return null; } return $match[1]; }, $newHTML );
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/reO8i
function name:  (null)
number of ops:  22
compiled vars:  !0 = $HTML, !1 = $listOfNegatives, !2 = $newHTML
line      #* E I O op                               fetch          ext  return  operands
-----------------------------------------------------------------------------------------
    3     0  E >   ASSIGN                                                       !0, 'some+data+from+%3Cspan+class%3D%22positive%22%3Eblahblah+test%3C%2Fspan%3E+was+not+%3Cspan+class%3D%22positive%22%3Estatistically+%3Cspan+class%3D%22positive%22%3Evalid%3C%2Fspan%3E%3C%2Fspan%3E+%3Cspan+class%3D%22positive%22%3Enot+statistically+valid%3C%2Fspan%3E'
    7     1        ASSIGN                                                       !1, <array>
   97     2        INIT_FCALL                                                   'negativehighlight'
          3        INIT_FCALL                                                   'checknegativesexistence'
          4        INIT_FCALL                                                   'extractwords'
          5        SEND_VAR                                                     !0
          6        DO_FCALL                                          0  $5      
          7        SEND_VAR                                                     $5
          8        SEND_VAR                                                     !1
          9        DO_FCALL                                          0  $6      
         10        SEND_VAR                                                     $6
         11        SEND_VAR                                                     !0
         12        DO_FCALL                                          0  $7      
         13        ASSIGN                                                       !2, $7
   99    14        INIT_FCALL                                                   'preg_replace_callback'
         15        SEND_VAL                                                     '%7E%28%3Cspan%5B%5E%3E%5D%2B%3E%28%5B%5E%3C%5D%2A%2B%3C%28%3F%21%2F%29%28%3F%3A%28%5Ba-zA-Z0-9%5D%2B%2B%29%5B%5E%3E%5D%2A%3E%5B%5E%3C%5D%2A%3C%2F%03%3E%7C%28%3F2%29%29%29%2A%5B%5E%3C%5D%2A%3C%2Fspan%3E%7C%28%3F%27single%27%3C%2F%5B%5E%3C%3E%5D%2B%3E%7C%3C%5B%5E%3C%3E%5D%2B%3E%29%29%7E'
  100    16        DECLARE_LAMBDA_FUNCTION                              ~9      [0]
  105    17        SEND_VAL                                                     ~9
  106    18        SEND_VAR                                                     !2
   99    19        DO_ICALL                                             $10     
  106    20        ECHO                                                         $10
  107    21      > RETURN                                                       1


Dynamic Functions:
Dynamic Function 0
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 43) Position 1 = 3, Position 2 = 4
Branch analysis from position: 3
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 4
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/reO8i
function name:  {closure:/in/reO8i:100}
number of ops:  7
compiled vars:  !0 = $match
line      #* E I O op                               fetch          ext  return  operands
-----------------------------------------------------------------------------------------
  100     0  E >   RECV                                                 !0      
  101     1        ISSET_ISEMPTY_DIM_OBJ                             0          !0, 'single'
          2      > JMPZ                                                         ~1, ->4
  102     3    > > RETURN                                                       null
  104     4    >   FETCH_DIM_R                                          ~2      !0, 1
          5      > RETURN                                                       ~2
  105     6*     > RETURN                                                       null

End of Dynamic Function 0

Function extractwords:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 77) Position 1 = 10, Position 2 = 16
Branch analysis from position: 10
2 jumps found. (Code = 78) Position 1 = 11, Position 2 = 16
Branch analysis from position: 11
1 jumps found. (Code = 42) Position 1 = 10
Branch analysis from position: 10
Branch analysis from position: 16
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 16
filename:       /in/reO8i
function name:  extractWords
number of ops:  19
compiled vars:  !0 = $HTML, !1 = $HTMLWords, !2 = $words, !3 = $word
line      #* E I O op                               fetch          ext  return  operands
-----------------------------------------------------------------------------------------
   14     0  E >   RECV                                                 !0      
   15     1        ASSIGN                                                       !1, <array>
   16     2        INIT_FCALL                                                   'preg_match_all'
          3        SEND_VAL                                                     '%7E%5Cb%28%3F%3C%21%5B%3C%2F%5D%29%5Cw%2B%5Cb%28%3F%21%5B%5E%3C%3E%5D%2B%3E%29%7E'
          4        SEND_VAR                                                     !0
          5        SEND_REF                                                     !2
          6        SEND_VAL                                                     256
          7        DO_ICALL                                                     
   17     8        FETCH_DIM_R                                          ~6      !2, 0
          9      > FE_RESET_R                                           $7      ~6, ->16
         10    > > FE_FETCH_R                                                   $7, !3, ->16
   18    11    >   FETCH_DIM_R                                          ~8      !3, 1
         12        FETCH_DIM_R                                          ~10     !3, 0
         13        ASSIGN_DIM                                                   !1, ~8
         14        OP_DATA                                                      ~10
   17    15      > JMP                                                          ->10
         16    >   FE_FREE                                                      $7
   20    17      > RETURN                                                       !1
   21    18*     > RETURN                                                       null

End of function extractwords

Function checknegativesexistence:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 77) Position 1 = 6, Position 2 = 50
Branch analysis from position: 6
2 jumps found. (Code = 78) Position 1 = 7, Position 2 = 50
Branch analysis from position: 7
2 jumps found. (Code = 77) Position 1 = 15, Position 2 = 47
Branch analysis from position: 15
2 jumps found. (Code = 78) Position 1 = 16, Position 2 = 47
Branch analysis from position: 16
2 jumps found. (Code = 43) Position 1 = 21, Position 2 = 23
Branch analysis from position: 21
2 jumps found. (Code = 43) Position 1 = 26, Position 2 = 34
Branch analysis from position: 26
1 jumps found. (Code = 42) Position 1 = 43
Branch analysis from position: 43
1 jumps found. (Code = 42) Position 1 = 15
Branch analysis from position: 15
Branch analysis from position: 34
2 jumps found. (Code = 46) Position 1 = 36, Position 2 = 40
Branch analysis from position: 36
2 jumps found. (Code = 43) Position 1 = 41, Position 2 = 43
Branch analysis from position: 41
1 jumps found. (Code = 42) Position 1 = 15
Branch analysis from position: 15
Branch analysis from position: 43
Branch analysis from position: 40
Branch analysis from position: 23
Branch analysis from position: 47
1 jumps found. (Code = 42) Position 1 = 6
Branch analysis from position: 6
Branch analysis from position: 47
Branch analysis from position: 50
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 50
filename:       /in/reO8i
function name:  checkNegativesExistence
number of ops:  53
compiled vars:  !0 = $HTMLWords, !1 = $listOfNegatives, !2 = $counter, !3 = $previousWordOffset, !4 = $subStrings, !5 = $string, !6 = $i, !7 = $stringWords, !8 = $wordIndex, !9 = $HTMLWord, !10 = $offset
line      #* E I O op                               fetch          ext  return  operands
-----------------------------------------------------------------------------------------
   30     0  E >   RECV                                                 !0      
          1        RECV                                                 !1      
   31     2        ASSIGN                                                       !2, 0
   32     3        ASSIGN                                                       !3, null
   33     4        ASSIGN                                                       !4, <array>
   35     5      > FE_RESET_R                                           $14     !1, ->50
          6    > > FE_FETCH_R                                           ~15     $14, !5, ->50
          7    >   ASSIGN                                                       !6, ~15
   36     8        INIT_FCALL                                                   'explode'
          9        SEND_VAL                                                     '+'
         10        SEND_VAR                                                     !5
         11        DO_ICALL                                             $17     
         12        ASSIGN                                                       !7, $17
   37    13        ASSIGN                                                       !8, 0
   38    14      > FE_RESET_R                                           $20     !0, ->47
         15    > > FE_FETCH_R                                           ~21     $20, !9, ->47
         16    >   ASSIGN                                                       !10, ~21
   39    17        COUNT                                                ~23     !7
         18        SUB                                                  ~24     ~23, 1
         19        IS_SMALLER                                                   ~24, !8
         20      > JMPZ                                                         ~25, ->23
   40    21    >   ASSIGN                                                       !8, 0
   41    22        PRE_INC                                                      !2
   44    23    >   FETCH_DIM_R                                          ~28     !7, !8
         24        IS_EQUAL                                                     !9, ~28
         25      > JMPZ                                                         ~29, ->34
   45    26    >   INIT_ARRAY                                           ~32     !9
         27        ADD_ARRAY_ELEMENT                                    ~32     !10
         28        ADD_ARRAY_ELEMENT                                    ~32     !3
         29        FETCH_DIM_W                                          $30     !4, !2
         30        ASSIGN_DIM                                                   $30
         31        OP_DATA                                                      ~32
   46    32        PRE_INC                                                      !8
   44    33      > JMP                                                          ->43
   48    34    >   ISSET_ISEMPTY_DIM_OBJ                             0  ~34     !4, !2
         35      > JMPZ_EX                                              ~34     ~34, ->40
         36    >   FETCH_DIM_R                                          ~35     !4, !2
         37        COUNT                                                ~36     ~35
         38        IS_SMALLER                                           ~37     0, ~36
         39        BOOL                                                 ~34     ~37
         40    > > JMPZ                                                         ~34, ->43
   49    41    >   UNSET_DIM                                                    !4, !2
   50    42        ASSIGN                                                       !8, 0
   52    43    >   STRLEN                                               ~39     !9
         44        ADD                                                  ~40     !10, ~39
         45        ASSIGN                                                       !3, ~40
   38    46      > JMP                                                          ->15
         47    >   FE_FREE                                                      $20
   54    48        PRE_INC                                                      !2
   35    49      > JMP                                                          ->6
         50    >   FE_FREE                                                      $14
   57    51      > RETURN                                                       !4
   58    52*     > RETURN                                                       null

End of function checknegativesexistence

Function negativehighlight:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 77) Position 1 = 6, Position 2 = 91
Branch analysis from position: 6
2 jumps found. (Code = 78) Position 1 = 7, Position 2 = 91
Branch analysis from position: 7
2 jumps found. (Code = 77) Position 1 = 10, Position 2 = 63
Branch analysis from position: 10
2 jumps found. (Code = 78) Position 1 = 11, Position 2 = 63
Branch analysis from position: 11
2 jumps found. (Code = 43) Position 1 = 20, Position 2 = 35
Branch analysis from position: 20
2 jumps found. (Code = 43) Position 1 = 28, Position 2 = 31
Branch analysis from position: 28
1 jumps found. (Code = 42) Position 1 = 34
Branch analysis from position: 34
2 jumps found. (Code = 43) Position 1 = 43, Position 2 = 62
Branch analysis from position: 43
2 jumps found. (Code = 43) Position 1 = 57, Position 2 = 59
Branch analysis from position: 57
1 jumps found. (Code = 42) Position 1 = 61
Branch analysis from position: 61
1 jumps found. (Code = 42) Position 1 = 10
Branch analysis from position: 10
Branch analysis from position: 59
1 jumps found. (Code = 42) Position 1 = 10
Branch analysis from position: 10
Branch analysis from position: 62
Branch analysis from position: 31
2 jumps found. (Code = 43) Position 1 = 43, Position 2 = 62
Branch analysis from position: 43
Branch analysis from position: 62
Branch analysis from position: 35
Branch analysis from position: 63
2 jumps found. (Code = 43) Position 1 = 79, Position 2 = 84
Branch analysis from position: 79
1 jumps found. (Code = 42) Position 1 = 90
Branch analysis from position: 90
1 jumps found. (Code = 42) Position 1 = 6
Branch analysis from position: 6
Branch analysis from position: 84
2 jumps found. (Code = 43) Position 1 = 87, Position 2 = 90
Branch analysis from position: 87
1 jumps found. (Code = 42) Position 1 = 6
Branch analysis from position: 6
Branch analysis from position: 90
Branch analysis from position: 63
Branch analysis from position: 91
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 91
filename:       /in/reO8i
function name:  negativeHighlight
number of ops:  94
compiled vars:  !0 = $subStrings, !1 = $HTML, !2 = $offset, !3 = $HTMLLength, !4 = $value, !5 = $key, !6 = $arrayOfWords, !7 = $word, !8 = $start, !9 = $defaultLength, !10 = $length, !11 = $string
line      #* E I O op                               fetch          ext  return  operands
-----------------------------------------------------------------------------------------
   67     0  E >   RECV                                                 !0      
          1        RECV                                                 !1      
   68     2        ASSIGN                                                       !2, 0
   69     3        STRLEN                                               ~13     !1
          4        ASSIGN                                                       !3, ~13
   71     5      > FE_RESET_R                                           $15     !0, ->91
          6    > > FE_FETCH_R                                           ~16     $15, !4, ->91
          7    >   ASSIGN                                                       !5, ~16
   72     8        ASSIGN                                                       !6, <array>
   73     9      > FE_RESET_R                                           $19     !4, ->63
         10    > > FE_FETCH_R                                                   $19, !7, ->63
   74    11    >   FETCH_DIM_R                                          ~21     !7, 0
         12        ASSIGN_DIM                                                   !6
         13        OP_DATA                                                      ~21
   75    14        INIT_FCALL                                                   'current'
         15        SEND_VAR                                                     !4
         16        DO_ICALL                                             $22     
         17        FETCH_DIM_R                                          ~23     !4, 0
         18        IS_EQUAL                                                     $22, ~23
         19      > JMPZ                                                         ~24, ->35
   76    20    >   FETCH_DIM_R                                          ~25     !7, 1
         21        FETCH_DIM_R                                          ~26     !7, 0
         22        STRLEN                                               ~27     ~26
         23        FRAMELESS_ICALL_3                substr              ~28     !1, ~25
         24        OP_DATA                                                      ~27
         25        FETCH_DIM_R                                          ~29     !7, 0
         26        IS_EQUAL                                                     ~28, ~29
         27      > JMPZ                                                         ~30, ->31
         28    >   FETCH_DIM_R                                          ~31     !7, 2
         29        QM_ASSIGN                                            ~32     ~31
         30      > JMP                                                          ->34
         31    >   FETCH_DIM_R                                          ~33     !7, 2
         32        ADD                                                  ~34     ~33, !2
         33        QM_ASSIGN                                            ~32     ~34
         34    >   ASSIGN                                                       !8, ~32
   78    35    >   INIT_FCALL                                                   'current'
         36        SEND_VAR                                                     !4
         37        DO_ICALL                                             $36     
         38        INIT_FCALL                                                   'end'
         39        SEND_REF                                                     !4
         40        DO_ICALL                                             $37     
         41        IS_EQUAL                                                     $36, $37
         42      > JMPZ                                                         ~38, ->62
   79    43    >   FETCH_DIM_R                                          ~39     !7, 1
         44        FETCH_DIM_R                                          ~40     !7, 0
         45        STRLEN                                               ~41     ~40
         46        ADD                                                  ~42     ~39, ~41
         47        SUB                                                  ~43     ~42, !8
         48        ASSIGN                                                       !9, ~43
   80    49        FETCH_DIM_R                                          ~45     !7, 1
         50        FETCH_DIM_R                                          ~46     !7, 0
         51        STRLEN                                               ~47     ~46
         52        FRAMELESS_ICALL_3                substr              ~48     !1, ~45
         53        OP_DATA                                                      ~47
         54        FETCH_DIM_R                                          ~49     !7, 0
         55        IS_IDENTICAL                                                 ~48, ~49
         56      > JMPZ                                                         ~50, ->59
         57    >   QM_ASSIGN                                            ~51     !9
         58      > JMP                                                          ->61
         59    >   ADD                                                  ~52     !9, !2
         60        QM_ASSIGN                                            ~51     ~52
         61    >   ASSIGN                                                       !10, ~51
   73    62    > > JMP                                                          ->10
         63    >   FE_FREE                                                      $19
   83    64        FRAMELESS_ICALL_2                implode             ~54     '+', !6
         65        ASSIGN                                                       !11, ~54
   84    66        INIT_FCALL                                                   'substr_replace'
         67        SEND_VAR                                                     !1
         68        ROPE_INIT                                         3  ~57     '%3Cspan+class%3D%22negative%22%3E'
         69        ROPE_ADD                                          1  ~57     ~57, !11
         70        ROPE_END                                          2  ~56     ~57, '%3C%2Fspan%3E'
         71        SEND_VAL                                                     ~56
         72        SEND_VAR                                                     !8
         73        SEND_VAR                                                     !10
         74        DO_ICALL                                             $59     
         75        ASSIGN                                                       !1, $59
   86    76        STRLEN                                               ~61     !1
         77        IS_SMALLER                                                   ~61, !3
         78      > JMPZ                                                         ~62, ->84
   87    79    >   STRLEN                                               ~63     !1
         80        SUB                                                  ~64     !3, ~63
         81        MUL                                                  ~65     ~64, -1
         82        ASSIGN                                                       !2, ~65
   86    83      > JMP                                                          ->90
   88    84    >   STRLEN                                               ~67     !1
         85        IS_SMALLER                                                   !3, ~67
         86      > JMPZ                                                         ~68, ->90
   89    87    >   STRLEN                                               ~69     !1
         88        SUB                                                  ~70     ~69, !3
         89        ASSIGN                                                       !2, ~70
   71    90    > > JMP                                                          ->6
         91    >   FE_FREE                                                      $15
   93    92      > RETURN                                                       !1
   94    93*     > RETURN                                                       null

End of function negativehighlight

Generated using Vulcan Logic Dumper, using php 8.5.0


preferences:
239.48 ms | 2377 KiB | 22 Q