如何将 html i 标记添加到与数组元素匹配的子字符串(如果它们还没有标记)

How to add html i tag to sub-strings that matched the elements of the array if they don't already have the tag

我想将 html i 标记添加到与数组元素匹配的字符串中的子字符串。如果匹配的子字符串有 i 标签,则不添加,否则添加。 这是我的示例代码。

   function itilizedWords($subjects){

  $arrayToSearch = array("Prima facie", "De facto", "Vis-à-vis", "De future",
      "De future", "De integro", "De integro", "De jure", 
      "Inter alia", "De novo", "Viz", "De minimis", "Res gestae",
     "De minimis non curat lex", "Res Gestae Divi Augusti", "et seq.",
     "et seq.", "Ex facie ", "A priori ", "A priori", "A posteriori",
     "Ex gratia", "A quo ", "Ex officio", "Ab extra", "Ab extra", "Ab 
      initio",
     "Ex post facto", "Absque hoc", "Factum", "Actori incumbit probation", 
     "Habeas corpus", 
      "Actus reus",  "Functus officio", "Ad coelom ", "Ad coelom ", "Ad 
      colligenda bona", 
      "Idem ", "Ad hoc", "In absentia", "Ad hominem", "In curia", "Ad idem", 
  "In extenso", 
     "Ad infinitum", "In futuro", "Ad litem", "In haec verba", "Ad quod damnum", "In limine",
      "Ad valorem","Pari material", "Adjournment sine die", "Adjournment sine die",
      "Amicus curiae", "Amicus curiae", "Animus nocendi", "Inter se", "Animus revertendi",
      "Intra vires", "Arguendo", "Arguendo", "Audi alteram partem", "Ipso facto", "Bona fide",
      "Jus cogens", "Mala fide", "Locus standi", "Certiorari", "Mandamus","Contra proferentem",
      "Contra proferentem","Coram non judice","Modus operandi",
      "Cuius est solum eius est usque ad coelum et ad inferos","Nemo judex in sua causa",
      "Status quo ante","Nisi","Stare decisis","Non est factum","Per se ","Per se ","Res gestae ",
      "Uberrima fides","Vice versa","Mutatis Mutandis","Wednesbury");

     $matchedwords=array();
    $offset = 0;
     $allpos = array();
    $pos=0;
    foreach ($arrayToSearch as $value) {
      while(($pos = strpos($subjects, $value, $offset))!== false){
       $offset   = $pos + 1;
        $allpos[] = $pos;
        $matchedwords[]= $value;
     if(strpos(substr($subjects, ($pos - 4), strlen($value)+ 6), '<i>')){
        return $subjects;
       } 
      else {
      return $replace = str_replace(substr($subjects, $pos, strlen($value)), '<i>'. substr($subjects, $pos, strlen($value)).'</i>', $subjects);
     $pos = $pos + 7;
       }

      }
    }

       }

       $subjects ="This is the Prima facie tried to do this it's been ....Prima facie <p><i>Prima facie</i></P> Prima facie  <p>Status quo ante  Uberrima fides</P> <i>Uberrima fides</i> <p>Mutatis Mutandis Wednesbury</p> <p><i>In futuro</i></p>";

         echo htmlentities(itilizedWords($subjects));

这段代码的问题在于它确实为所有匹配的单词添加了 i 标记,并使一些子字符串具有双 i 标记。所以,我想避免。欢迎任何帮助,并在此先感谢您。

从列表中替换时的主要问题是部分重复:

例如,您有 "De minimis""De minimis non curat lex"

在这样的文本中:

De minimis non curat lex

结果会是

<i><i>De minimis</i> non curat lex<i>

此外,您在原始文本中已经格式化了标签。所以,你需要在替换之前检查这个,以避免重复替换

此外,代码只会 运行 仅针对找到的第一个单词,因为您在 while 内使用 return。考虑在不需要任何操作时使用 continue,return 稍后在最后显示结果。

最后,在整个字符串中使用 str_replace 当您重复调用它时,总是会重复替换。

这是经过一些改进的更新代码:

<?php

function itilizedWords($subjects){

  $arrayToSearch = array("Prima facie", "De facto", "Vis-à-vis", "De future",
      "De future", "De integro", "De integro", "De jure", 
      "Inter alia", "De novo", "Viz", "De minimis", "Res gestae",
     "De minimis non curat lex", "Res Gestae Divi Augusti", "et seq.",
     "et seq.", "Ex facie ", "A priori ", "A priori", "A posteriori",
     "Ex gratia", "A quo ", "Ex officio", "Ab extra", "Ab extra", "Ab 
      initio",
     "Ex post facto", "Absque hoc", "Factum", "Actori incumbit probation", 
     "Habeas corpus", 
      "Actus reus",  "Functus officio", "Ad coelom ", "Ad coelom ", "Ad 
      colligenda bona", 
      "Idem ", "Ad hoc", "In absentia", "Ad hominem", "In curia", "Ad idem", 
  "In extenso", 
     "Ad infinitum", "In futuro", "Ad litem", "In haec verba", "Ad quod damnum", "In limine",
      "Ad valorem","Pari material", "Adjournment sine die", "Adjournment sine die",
      "Amicus curiae", "Amicus curiae", "Animus nocendi", "Inter se", "Animus revertendi",
      "Intra vires", "Arguendo", "Arguendo", "Audi alteram partem", "Ipso facto", "Bona fide",
      "Jus cogens", "Mala fide", "Locus standi", "Certiorari", "Mandamus","Contra proferentem",
      "Contra proferentem","Coram non judice","Modus operandi",
      "Cuius est solum eius est usque ad coelum et ad inferos","Nemo judex in sua causa",
      "Status quo ante","Nisi","Stare decisis","Non est factum","Per se ","Per se ","Res gestae ",
      "Uberrima fides","Vice versa","Mutatis Mutandis","Wednesbury");

     $matchedwords=array();
    $offset = 0;
     $allpos = array();
    $pos=0;
    foreach ($arrayToSearch as $value) {
      while(($pos = strpos($subjects, $value, $offset))!== false){
        $pos2=strpos($subjects, "<i>$value</i>", $offset) ;
        $offset   = $pos + 1;
          if ($pos2==$pos-3){
               // $value is yet between tags
               $offset   = $pos + 5;
              continue;
          }
        $prev=substr($subjects,0,$pos);
        $next=substr($subjects,$pos+strlen($value));  

       $subjects = $prev . '<i>'. $value.'</i>'.  $next;
       $offset +=7;

      }
    }
    return $subjects;

       }

       $subjects ="This is the Prima facie tried to do this it's been ....Prima facie <p><i>Prima facie</i></P> Prima facie  <p>Status quo ante  Uberrima fides</P> <i>Uberrima fides</i> <p>Mutatis Mutandis Wednesbury</p> <p><i>In futuro</i></p>";

         echo htmlentities(itilizedWords($subjects));
?>

我可能会这样做:

<?php

function itilizedWords( $subjects, $arrayToSearch ){

    foreach( $arrayToSearch as $chars )
    {
        $regex = '|(?!<i>)(' . $chars . ')(?!</i>)|';

        if( preg_match( $regex, $subjects, $matches) )
            $subjects = preg_replace( $regex, '<i>' . $matches[0] . '</i>', $subjects );
    }

    return $subjects;
}

$arrayToSearch = [
    "Prima facie", "De facto", "Vis-à-vis", "De future",
    "De future", "De integro", "De integro", "De jure", "Inter alia", "De novo", 
    "Viz", "De minimis", "Res gestae","De minimis non curat lex", 
    "Res Gestae Divi Augusti", "et seq.","et seq.", "Ex facie ", "A priori ", 
    "A priori", "A posteriori","Ex gratia", "A quo ", "Ex officio", "Ab extra", 
    "Ab extra", "Ab initio","Ex post facto", "Absque hoc", "Factum", 
    "Actori incumbit probation", "Habeas corpus", "Actus reus",  "Functus officio", 
    "Ad coelom ", "Ad coelom ", "Ad colligenda bona", "Idem ", "Ad hoc", "In absentia", 
    "Ad hominem", "In curia", "Ad idem", "In extenso", "Ad infinitum", "In futuro", 
    "Ad litem", "In haec verba", "Ad quod damnum", "In limine","Ad valorem",
    "Pari material", "Adjournment sine die", "Adjournment sine die","Amicus curiae", 
    "Amicus curiae", "Animus nocendi", "Inter se", "Animus revertendi","Intra vires", 
    "Arguendo", "Arguendo", "Audi alteram partem", "Ipso facto", "Bona fide",
    "Jus cogens", "Mala fide", "Locus standi", "Certiorari", "Mandamus",
    "Contra proferentem","Contra proferentem","Coram non judice","Modus operandi",
    "Cuius est solum eius est usque ad coelum et ad inferos","Nemo judex in sua causa",
    "Status quo ante","Nisi","Stare decisis","Non est factum","Per se ","Per se ",
    "Res gestae ","Uberrima fides","Vice versa","Mutatis Mutandis","Wednesbury"
];

$subjects ="This is the Prima facie tried to do this it's been ....Prima facie <p><i>Prima facie</i></P> Prima facie  <p>Status quo ante  Uberrima fides</P> <i>Uberrima fides</i> <p>Mutatis Mutandis Wednesbury</p> <p><i>In futuro</i></p>";

echo htmlentities( itilizedWords( $subjects, $arrayToSearch ) );