3v4l.org

run code in 300+ 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}
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 = 100
Branch analysis from position: 6
2 jumps found. (Code = 78) Position 1 = 7, Position 2 = 100
Branch analysis from position: 7
2 jumps found. (Code = 77) Position 1 = 10, Position 2 = 69
Branch analysis from position: 10
2 jumps found. (Code = 78) Position 1 = 11, Position 2 = 69
Branch analysis from position: 11
2 jumps found. (Code = 43) Position 1 = 20, Position 2 = 38
Branch analysis from position: 20
2 jumps found. (Code = 43) Position 1 = 31, Position 2 = 34
Branch analysis from position: 31
1 jumps found. (Code = 42) Position 1 = 37
Branch analysis from position: 37
2 jumps found. (Code = 43) Position 1 = 46, Position 2 = 68
Branch analysis from position: 46
2 jumps found. (Code = 43) Position 1 = 63, Position 2 = 65
Branch analysis from position: 63
1 jumps found. (Code = 42) Position 1 = 67
Branch analysis from position: 67
1 jumps found. (Code = 42) Position 1 = 10
Branch analysis from position: 10
Branch analysis from position: 65
1 jumps found. (Code = 42) Position 1 = 10
Branch analysis from position: 10
Branch analysis from position: 68
Branch analysis from position: 34
2 jumps found. (Code = 43) Position 1 = 46, Position 2 = 68
Branch analysis from position: 46
Branch analysis from position: 68
Branch analysis from position: 38
Branch analysis from position: 69
2 jumps found. (Code = 43) Position 1 = 88, Position 2 = 93
Branch analysis from position: 88
1 jumps found. (Code = 42) Position 1 = 99
Branch analysis from position: 99
1 jumps found. (Code = 42) Position 1 = 6
Branch analysis from position: 6
Branch analysis from position: 93
2 jumps found. (Code = 43) Position 1 = 96, Position 2 = 99
Branch analysis from position: 96
1 jumps found. (Code = 42) Position 1 = 6
Branch analysis from position: 6
Branch analysis from position: 99
Branch analysis from position: 69
Branch analysis from position: 100
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 100
filename:       /in/reO8i
function name:  negativeHighlight
number of ops:  103
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, ->100
          6    > > FE_FETCH_R                                       ~16     $15, !4, ->100
          7    >   ASSIGN                                                   !5, ~16
   72     8        ASSIGN                                                   !6, <array>
   73     9      > FE_RESET_R                                       $19     !4, ->69
         10    > > FE_FETCH_R                                               $19, !7, ->69
   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, ->38
   76    20    >   INIT_FCALL                                               'substr'
         21        SEND_VAR                                                 !1
         22        FETCH_DIM_R                                      ~25     !7, 1
         23        SEND_VAL                                                 ~25
         24        FETCH_DIM_R                                      ~26     !7, 0
         25        STRLEN                                           ~27     ~26
         26        SEND_VAL                                                 ~27
         27        DO_ICALL                                         $28     
         28        FETCH_DIM_R                                      ~29     !7, 0
         29        IS_EQUAL                                                 $28, ~29
         30      > JMPZ                                                     ~30, ->34
         31    >   FETCH_DIM_R                                      ~31     !7, 2
         32        QM_ASSIGN                                        ~32     ~31
         33      > JMP                                                      ->37
         34    >   FETCH_DIM_R                                      ~33     !7, 2
         35        ADD                                              ~34     ~33, !2
         36        QM_ASSIGN                                        ~32     ~34
         37    >   ASSIGN                                                   !8, ~32
   78    38    >   INIT_FCALL                                               'current'
         39        SEND_VAR                                                 !4
         40        DO_ICALL                                         $36     
         41        INIT_FCALL                                               'end'
         42        SEND_REF                                                 !4
         43        DO_ICALL                                         $37     
         44        IS_EQUAL                                                 $36, $37
         45      > JMPZ                                                     ~38, ->68
   79    46    >   FETCH_DIM_R                                      ~39     !7, 1
         47        FETCH_DIM_R                                      ~40     !7, 0
         48        STRLEN                                           ~41     ~40
         49        ADD                                              ~42     ~39, ~41
         50        SUB                                              ~43     ~42, !8
         51        ASSIGN                                                   !9, ~43
   80    52        INIT_FCALL                                               'substr'
         53        SEND_VAR                                                 !1
         54        FETCH_DIM_R                                      ~45     !7, 1
         55        SEND_VAL                                                 ~45
         56        FETCH_DIM_R                                      ~46     !7, 0
         57        STRLEN                                           ~47     ~46
         58        SEND_VAL                                                 ~47
         59        DO_ICALL                                         $48     
         60        FETCH_DIM_R                                      ~49     !7, 0
         61        IS_IDENTICAL                                             $48, ~49
         62      > JMPZ                                                     ~50, ->65
         63    >   QM_ASSIGN                                        ~51     !9
         64      > JMP                                                      ->67
         65    >   ADD                                              ~52     !9, !2
         66        QM_ASSIGN                                        ~51     ~52
         67    >   ASSIGN                                                   !10, ~51
   73    68    > > JMP                                                      ->10
         69    >   FE_FREE                                                  $19
   83    70        INIT_FCALL                                               'implode'
         71        SEND_VAL                                                 '+'
         72        SEND_VAR                                                 !6
         73        DO_ICALL                                         $54     
         74        ASSIGN                                                   !11, $54
   84    75        INIT_FCALL                                               'substr_replace'
         76        SEND_VAR                                                 !1
         77        ROPE_INIT                                     3  ~57     '%3Cspan+class%3D%22negative%22%3E'
         78        ROPE_ADD                                      1  ~57     ~57, !11
         79        ROPE_END                                      2  ~56     ~57, '%3C%2Fspan%3E'
         80        SEND_VAL                                                 ~56
         81        SEND_VAR                                                 !8
         82        SEND_VAR                                                 !10
         83        DO_ICALL                                         $59     
         84        ASSIGN                                                   !1, $59
   86    85        STRLEN                                           ~61     !1
         86        IS_SMALLER                                               ~61, !3
         87      > JMPZ                                                     ~62, ->93
   87    88    >   STRLEN                                           ~63     !1
         89        SUB                                              ~64     !3, ~63
         90        MUL                                              ~65     ~64, -1
         91        ASSIGN                                                   !2, ~65
   86    92      > JMP                                                      ->99
   88    93    >   STRLEN                                           ~67     !1
         94        IS_SMALLER                                               !3, ~67
         95      > JMPZ                                                     ~68, ->99
   89    96    >   STRLEN                                           ~69     !1
         97        SUB                                              ~70     ~69, !3
         98        ASSIGN                                                   !2, ~70
   71    99    > > JMP                                                      ->6
        100    >   FE_FREE                                                  $15
   93   101      > RETURN                                                   !1
   94   102*     > RETURN                                                   null

End of function negativehighlight

Generated using Vulcan Logic Dumper, using php 8.0.0


preferences:
150.57 ms | 1033 KiB | 24 Q