String conversion algorithm

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • John van Terheijden

    String conversion algorithm

    Hi.

    I'm trying to make a conversion algorithm that colors even and odd words in
    a HTML string with <div> tags.

    // input text with all sorts of HTML tags and whitespace
    $str = "<h1>Title here</h1>
    <p>This is a <strong>nice</strong> <img src="picture.gi f" /><br>
    and some nice text </p>";

    // color the words and echo
    echo color_words($st r);

    Would like the output to be:
    <h1><div class="c1">Titl e</div> <div class="c2">here </div></h1>
    <p><div class="c1">This </div> <div class="c2">is</div> <div
    class="c1">a</div> <strong><div class="c2">nice </div></strong> <img
    src="picture.gi f" /><br>
    <div class="c1">and</div> <div class="c2">some </div> <div
    class="c1">nice </div> <div class="c2">text </div> </p>

    I tried it with some nested for and while loops, but kept getting infinite
    loops, char. skipping problems, etc.

    Maybe regular expressions is the answer, but I have very little (and bad)
    experience with those.

    I'm sure there are lots of you would could solve this in a couple of
    seconds; please do so and help me out! :)

    Thanks,

    - John


  • steve

    #2
    Re: String conversion algorithm

    "John van Terheijde" wrote:[color=blue]
    > Hi.
    >
    > I’m trying to make a conversion algorithm that colors even and
    > odd words in
    > a HTML string with <div> tags.
    >
    > // input text with all sorts of HTML tags and whitespace
    > $str = "<h1>Title here</h1>
    > <p>This is a <strong>nice</strong> <img
    > src="picture.gi f" /><br>
    > and some nice text </p>";
    >
    > // color the words and echo
    > echo color_words($st r);
    >
    > Would like the output to be:
    > <h1><div class="c1">Titl e</div> <div
    > class="c2">here </div></h1>
    > <p><div class="c1">This </div> <div
    > class="c2">is</div> <div
    > class="c1">a</div> <strong><div
    > class="c2">nice </div></strong> <img
    > src="picture.gi f" /><br>
    > <div class="c1">and</div> <div
    > class="c2">some </div> <div
    > class="c1">nice </div> <div class="c2">text </div>
    > </p>
    >
    > I tried it with some nested for and while loops, but kept getting
    > infinite
    > loops, char. skipping problems, etc.
    >
    > Maybe regular expressions is the answer, but I have very little[/color]
    (and[color=blue]
    > bad)
    > experience with those.
    >
    > I’m sure there are lots of you would could solve this in a
    > couple of
    > seconds; please do so and help me out!
    >
    > Thanks,
    >
    > - John[/color]

    I give you a non-exact solution:

    $array = explode(" ", $str); //you can use "split" for finer
    splitting
    foreach ($array as $key => $word) {

    //detect odd/even
    if (intval($key/2) == $key/2) $word = "<color...> " . $word .
    "<...>";
    else $word = "the other color" . $word . "other color stuff"
    }

    $out = implode(" ", $array);
    echo $out;

    Hope this helps get you started

    --
    http://www.dbForumz.com/ This article was posted by author's request
    Articles individually checked for conformance to usenet standards
    Topic URL: http://www.dbForumz.com/PHP-String-c...ict133295.html
    Visit Topic URL to contact author (reg. req'd). Report abuse: http://www.dbForumz.com/eform.php?p=445292

    Comment

    • Blackie

      #3
      Re: String conversion algorithm

      this code has one small bug - works with empty words

      try to convert this: "evenword1 oddword1 evenword2 oddword2" (notice two
      spaces between oddword1 and evenword2)
      it produces this result: "<evencolor>eve nword1</...>
      <oddcolor>oddwo rd1</...> <evencolor></...> <oddcolor>evenw ord2</...>
      <evencolor>oddw ord2</...>"
      but we need this result: "<evencolor>eve nword1</...>
      <oddcolor>oddwo rd1</...> <evencolor>even word2</...>
      <oddcolor>oddwo rd2</...>"

      so try small correcture:

      [PHP]
      $array = explode(" ", $str); //you can use "split" for finer splitting
      $i = 1;
      foreach ($array as $key => $word) if($word != "") {
      if ($i%2 == 0) $word = "<color...> " . $word . "<...>";
      else $word = "the other color" . $word . "other color stuff"
      $i++;
      }
      [/PHP]


      "steve" <UseLinkToEmail @dbForumz.com> pí¹e v diskusním pøíspìvku
      news:10gamvi5cm kpb68@news.supe rnews.com...[color=blue]
      > "John van Terheijde" wrote:[color=green]
      > > Hi.
      > >
      > > I’m trying to make a conversion algorithm that colors even and
      > > odd words in
      > > a HTML string with <div> tags.
      > >
      > > // input text with all sorts of HTML tags and whitespace
      > > $str = "<h1>Title here</h1>
      > > <p>This is a <strong>nice</strong> <img
      > > src="picture.gi f" /><br>
      > > and some nice text </p>";
      > >
      > > // color the words and echo
      > > echo color_words($st r);
      > >
      > > Would like the output to be:
      > > <h1><div class="c1">Titl e</div> <div
      > > class="c2">here </div></h1>
      > > <p><div class="c1">This </div> <div
      > > class="c2">is</div> <div
      > > class="c1">a</div> <strong><div
      > > class="c2">nice </div></strong> <img
      > > src="picture.gi f" /><br>
      > > <div class="c1">and</div> <div
      > > class="c2">some </div> <div
      > > class="c1">nice </div> <div class="c2">text </div>
      > > </p>
      > >
      > > I tried it with some nested for and while loops, but kept getting
      > > infinite
      > > loops, char. skipping problems, etc.
      > >
      > > Maybe regular expressions is the answer, but I have very little[/color]
      > (and[color=green]
      > > bad)
      > > experience with those.
      > >
      > > I’m sure there are lots of you would could solve this in a
      > > couple of
      > > seconds; please do so and help me out!
      > >
      > > Thanks,
      > >
      > > - John[/color]
      >
      > I give you a non-exact solution:
      >
      > $array = explode(" ", $str); //you can use "split" for finer
      > splitting
      > foreach ($array as $key => $word) {
      >
      > //detect odd/even
      > if (intval($key/2) == $key/2) $word = "<color...> " . $word .
      > "<...>";
      > else $word = "the other color" . $word . "other color stuff"
      > }
      >
      > $out = implode(" ", $array);
      > echo $out;
      >
      > Hope this helps get you started
      >
      > --
      > http://www.dbForumz.com/ This article was posted by author's request
      > Articles individually checked for conformance to usenet standards
      > Topic URL:[/color]
      http://www.dbForumz.com/PHP-String-c...ict133295.html[color=blue]
      > Visit Topic URL to contact author (reg. req'd). Report abuse:[/color]



      Comment

      • Blackie

        #4
        Re: String conversion algorithm

        using some loop is good idea, it's simple :))
        try something like this, you can enhance it to detect more separators (not
        only space), to ignore HTML tags and so on...

        [PHP]
        $src = "evenword1 oddword1 evenword2 oddword2";
        $tmp = $src;
        $dst = "";
        $i = 0;
        do{
        $pos = strpos($tmp, " ");
        if($pos !== false) // separator found, we have "word"
        {
        $word = substr($tmp, 0, $pos); // extract word
        if($word != "") // isn't it
        empty??
        {
        if($i%2 == 0) $word = "<color1>".$wor d."</color1>"; // colorize it
        else $word = "<color2>".$wor d."</color2>";
        $i++; // increase word
        counter
        }
        $dst .= $word.substr($t mp, $pos, 1); // append
        colorized word and separator to destination
        $tmp = substr($tmp, $pos+1); // and trim used
        part from temporary
        }
        else // no other separator found, we have last word
        {
        if($tmp != "") // isn't it
        empty??
        {
        if($i%2 == 0) $tmp = "<color1>".$tmp ."</color1>"; // colorize it
        else $tmp = "<color2>".$tmp ."</color2>";
        $i++; // increase word
        counter
        }
        $dst .= $tmp;
        unset($tmp);
        break;
        }
        }while(1);

        echo "<pre>";
        echo "source: ".htmlspecialch ars($src)."<br> ";
        echo "destinatio n: ".htmlspecialch ars($dst)."<br> ";
        echo "we have ".$i." words";
        echo "</pre>";
        [/PHP]


        "John van Terheijden" <vanterheijden_ avoidin_spam@ho me.nl> pí¹e v diskusním
        pøíspìvku news:ce3frp$rkm $1@news5.tilbu1 .nb.home.nl...[color=blue]
        > Hi.
        >
        > I'm trying to make a conversion algorithm that colors even and odd words[/color]
        in[color=blue]
        > a HTML string with <div> tags.
        >
        > // input text with all sorts of HTML tags and whitespace
        > $str = "<h1>Title here</h1>
        > <p>This is a <strong>nice</strong> <img src="picture.gi f" /><br>
        > and some nice text </p>";
        >
        > // color the words and echo
        > echo color_words($st r);
        >
        > Would like the output to be:
        > <h1><div class="c1">Titl e</div> <div class="c2">here </div></h1>
        > <p><div class="c1">This </div> <div class="c2">is</div> <div
        > class="c1">a</div> <strong><div class="c2">nice </div></strong> <img
        > src="picture.gi f" /><br>
        > <div class="c1">and</div> <div class="c2">some </div> <div
        > class="c1">nice </div> <div class="c2">text </div> </p>
        >
        > I tried it with some nested for and while loops, but kept getting infinite
        > loops, char. skipping problems, etc.
        >
        > Maybe regular expressions is the answer, but I have very little (and bad)
        > experience with those.
        >
        > I'm sure there are lots of you would could solve this in a couple of
        > seconds; please do so and help me out! :)
        >
        > Thanks,
        >
        > - John
        >
        >[/color]


        Comment

        • John van Terheijden

          #5
          Re: String conversion algorithm

          Thanks for the replies!

          The given solutions didn't do anything with the fact that <tags> shouldn't
          be colored. I fiddled some more with my initial for loop and came up with a
          solution. The main difference between this and earlier attempts is that I
          now haven't got nested for and while loops, so every time only 1 character
          is handled.

          function color($string) {
          $whitespace = explode('-', " -\n-\r- -\0-\x0B");
          $out = '<span>';
          $color1 = true;
          $inTag = false;
          $inColor = true;
          for ($i = 0; $i < strlen($string) ; $i++) {
          $char = $string[$i];

          // in a tag
          if ($inTag) {
          if ($char == '>') $inTag = false;
          }

          // not in a tag
          else {

          // starting a tag
          if ($char == '<') {
          $inTag = true;
          if ($inColor) {
          $out .= '</span>';
          $inColor = false;
          }
          }

          // in whitespace
          elseif (in_array($char , $whitespace)) {
          if ($inColor) {
          $out .= '</span>';
          $inColor = false;
          }
          }

          // in "normal" text
          else {
          if (!$inColor) {
          if ($color1) $out .= '<span class="c1">';
          else $out .= '<span class="c2">';
          $color1 = !$color1;
          $inColor = true;
          }
          }
          }
          $out .= $char;
          }
          $out .= '</span>';
          return $out;
          }


          Thanks,

          - John

          "John van Terheijden" <vanterheijden_ avoidin_spam@ho me.nl> schreef in
          bericht news:ce3frp$rkm $1@news5.tilbu1 .nb.home.nl...[color=blue]
          > Hi.
          >
          > I'm trying to make a conversion algorithm that colors even and odd words[/color]
          in[color=blue]
          > a HTML string with <div> tags.
          >
          > // input text with all sorts of HTML tags and whitespace
          > $str = "<h1>Title here</h1>
          > <p>This is a <strong>nice</strong> <img src="picture.gi f" /><br>
          > and some nice text </p>";
          >
          > // color the words and echo
          > echo color_words($st r);
          >
          > Would like the output to be:
          > <h1><div class="c1">Titl e</div> <div class="c2">here </div></h1>
          > <p><div class="c1">This </div> <div class="c2">is</div> <div
          > class="c1">a</div> <strong><div class="c2">nice </div></strong> <img
          > src="picture.gi f" /><br>
          > <div class="c1">and</div> <div class="c2">some </div> <div
          > class="c1">nice </div> <div class="c2">text </div> </p>
          >
          > I tried it with some nested for and while loops, but kept getting infinite
          > loops, char. skipping problems, etc.
          >
          > Maybe regular expressions is the answer, but I have very little (and bad)
          > experience with those.
          >
          > I'm sure there are lots of you would could solve this in a couple of
          > seconds; please do so and help me out! :)
          >
          > Thanks,
          >
          > - John
          >
          >[/color]


          Comment

          • Michael Fesser

            #6
            Re: String conversion algorithm

            .oO(John van Terheijden)
            [color=blue]
            >The given solutions didn't do anything with the fact that <tags> shouldn't
            >be colored. I fiddled some more with my initial for loop and came up with a
            >solution. [...][/color]

            But there are some bugs, the beginning and end of your teststring look
            like this:

            <span></span><h1><span class="c1">Titl e</span> ...
            ^^^^^^^^^^^^^

            .... <span class="c2">text </span> </p></span>
            ^^^^^^^

            I've played around a bit with regular expressions:

            function color_words($st ring) {
            $color = 2;
            $pattern = '#[^\s<>]+(?![^<]*>)#e';
            $replace = '"<span class=\"c".($co lor = 3-$color)."\">$0</span>"';
            return preg_replace($p attern, $replace, $string);
            }

            With my teststrings it works, but it's quite possible that there are
            situations where it'll fail, you have to test it.

            Micha

            Comment

            • John van Terheijden

              #7
              Re: String conversion algorithm

              Hi Michael.

              Thanks for the reply.

              You were right about the "bugs". The opening and closing <span> </span> were
              needed in earlier attempts. I solved it better now:
              ---
              function color($string) {
              $whitespace = explode('-', " -\n-\r-\t-\0-\x0B");
              $color1 = true;
              $inTag = false;
              $inColor = false;

              for ($i = 0; $i < strlen($string) ; $i++) {
              $char = $string[$i];

              // in a tag
              if ($inTag) {
              if ($char == '>') $inTag = false;
              }

              // not in a tag
              else {

              // starting a tag
              if ($char == '<') {
              $inTag = true;
              if ($inColor) {
              $out .= '</span>';
              $inColor = false;
              }
              }

              // in whitespace
              elseif (in_array($char , $whitespace)) {
              if ($inColor) {
              $out .= '</span>';
              $inColor = false;
              }
              }

              // in "normal" text
              else {
              if (!$inColor) {
              if ($color1) $out .= '<span class="c1">';
              else $out .= '<span class="c2">';
              $color1 = !$color1;
              $inColor = true;
              }
              }
              }
              $out .= $char;
              }
              if ($inColor) $out .= '</span>';
              return $out;
              }
              ---

              I tested your code and with my test HTML it works just fine. I think I'll
              use your code now, for it's nice and short (and prob. faster) and switch
              back to mine when changes or additional stuff is needed :)

              Thanks!

              - John

              "Michael Fesser" <netizen@gmx.ne t> schreef in bericht
              news:38qcg0helf jm8hhd16bjo0gqb 3b90ivbpr@4ax.c om...[color=blue]
              > .oO(John van Terheijden)
              >[color=green]
              > >The given solutions didn't do anything with the fact that <tags>[/color][/color]
              shouldn't[color=blue][color=green]
              > >be colored. I fiddled some more with my initial for loop and came up with[/color][/color]
              a[color=blue][color=green]
              > >solution. [...][/color]
              >
              > But there are some bugs, the beginning and end of your teststring look
              > like this:
              >
              > <span></span><h1><span class="c1">Titl e</span> ...
              > ^^^^^^^^^^^^^
              >
              > ... <span class="c2">text </span> </p></span>
              > ^^^^^^^
              >
              > I've played around a bit with regular expressions:
              >
              > function color_words($st ring) {
              > $color = 2;
              > $pattern = '#[^\s<>]+(?![^<]*>)#e';
              > $replace = '"<span class=\"c".($co lor = 3-$color)."\">$0</span>"';
              > return preg_replace($p attern, $replace, $string);
              > }
              >
              > With my teststrings it works, but it's quite possible that there are
              > situations where it'll fail, you have to test it.
              >
              > Micha[/color]


              Comment

              • Michael Fesser

                #8
                Re: String conversion algorithm

                .oO(John van Terheijden)
                [color=blue]
                >You were right about the "bugs". The opening and closing <span> </span> were
                >needed in earlier attempts. I solved it better now:[/color]

                Seems to work, but there are still some little issues:
                [color=blue]
                >function color($string) {
                > $whitespace = explode('-', " -\n-\r-\t-\0-\x0B");
                > $color1 = true;
                > $inTag = false;
                > $inColor = false;[/color]

                You should add an

                $out = '';

                at the beginning, or you'll get a notice on a line with

                $out .= ...

                (if error_reporting is set to E_ALL, which should be the case on
                development systems).
                [color=blue]
                > for ($i = 0; $i < strlen($string) ; $i++) {
                > $char = $string[$i];[/color]

                Use curly braces for accessing single chars in a string:

                $char = $string{$i};

                Using array-brackets for this is still allowed for backwards
                compatibility, but deprecated.
                [color=blue]
                >I tested your code and with my test HTML it works just fine. I think I'll
                >use your code now, for it's nice and short (and prob. faster) [...][/color]

                I have done a little test on my "server" (P100, 64MB RAM ;) ): With your
                given teststring the regular expression method was 2-3 times faster,
                with a longer string (a complete webpage) it was still 2 times faster.

                Micha

                Comment

                • John van Terheijden

                  #9
                  Re: String conversion algorithm

                  You're right about the notice and the curly braces. I didn't know about
                  them, it worked with [], so I thought that was the way..

                  Thanks for the testing!

                  - John

                  "Michael Fesser" <netizen@gmx.ne t> schreef in bericht
                  news:la2dg0tpnl s0vte488gsmupck vpuav3r9l@4ax.c om...[color=blue]
                  > .oO(John van Terheijden)
                  >[color=green]
                  > >You were right about the "bugs". The opening and closing <span> </span>[/color][/color]
                  were[color=blue][color=green]
                  > >needed in earlier attempts. I solved it better now:[/color]
                  >
                  > Seems to work, but there are still some little issues:
                  >[color=green]
                  > >function color($string) {
                  > > $whitespace = explode('-', " -\n-\r-\t-\0-\x0B");
                  > > $color1 = true;
                  > > $inTag = false;
                  > > $inColor = false;[/color]
                  >
                  > You should add an
                  >
                  > $out = '';
                  >
                  > at the beginning, or you'll get a notice on a line with
                  >
                  > $out .= ...
                  >
                  > (if error_reporting is set to E_ALL, which should be the case on
                  > development systems).
                  >[color=green]
                  > > for ($i = 0; $i < strlen($string) ; $i++) {
                  > > $char = $string[$i];[/color]
                  >
                  > Use curly braces for accessing single chars in a string:
                  >
                  > $char = $string{$i};
                  >
                  > Using array-brackets for this is still allowed for backwards
                  > compatibility, but deprecated.
                  >[color=green]
                  > >I tested your code and with my test HTML it works just fine. I think I'll
                  > >use your code now, for it's nice and short (and prob. faster) [...][/color]
                  >
                  > I have done a little test on my "server" (P100, 64MB RAM ;) ): With your
                  > given teststring the regular expression method was 2-3 times faster,
                  > with a longer string (a complete webpage) it was still 2 times faster.
                  >
                  > Micha[/color]


                  Comment

                  Working...