1

I have a form with a textarea field. User inputs item in this list like this

 * first item in list
 * second item in list
Free text not in list

I would like this to be output where the asterix is converted to an bullet list. and the text without asterix is not in the bulleted list.

like:


  • first item in list
  • second item in list

Free text not in list


Have tried:

$text = preg_replace("/\-+(.*)?/i","<li>$1</li>",$input);
$output = preg_replace("/(\<\/ul\>(.*)\<ul\>*)+/","",$text);

But i'm struggling to get my head around the preg_replace(), and tried to search for better solutions. So this code i found is not working.

Bengt
  • 65
  • 1
  • 7

3 Answers3

1

I wrote a little script to demonstrate if you don't want to use regex.

Anyway it sounds like you want to parse markdown and there's plenty of libraries to parse that. These libraries are much more reliable than trying to do it all yourself as there are plenty of edge cases.

<?php
$input = [];  // Assuming this is the list of lines to output.
$output = []; // Lines to output later.

$listOpen = false; // Whether we are currently in an <ul> list.

foreach ($input as $line) {
    // Check if string starts with a *, ignoring preceding whitespace.
    if (str_starts_with(ltrim($line), '*')) {
        // Open list if it is not open yet.
        if ($listOpen === false) {
            $output[] = "<ul>";
            $listOpen = true;
        }

        // Get text without preceding whitespace and *
        $text = ltrim(substr($line, strpos($list, '*')));

        // Output list item
        $output[] = "<li>$text</li>";

        // Continue to the next line and don't process code below.
        continue;
    }

    // Close list with </ul> if it has been opened before.
    if ($listOpen === true) {
        $output[] = "</ul>";
        $listOpen = false;
    }

    // Output line in paragraph tag.
    $output[] = "<p>$line</p>";
}

// Make sure the list is closed.
if ($listOpen === true) {
    $output[] = "</ul>";
    $listOpen = false;
}

// Output each line on a new line (actual newline \n or \r\n, not a HTML <br/>)
echo implode($output, PHP_EOL);
M. de Boer
  • 51
  • 4
  • This worked. Thanx... But had to change a line from: `$text = ltrim(substr($line, strpos($list, '*')));`, to: `$text = ltrim(substr($line, strpos($line, '*')+1));` It failed because $list string didn't exist. replaced it by $line, but had to increase that number by 1 to remove the *. – Bengt May 30 '21 at 20:16
  • 1
    You are right, my bad! Glad it worked! – M. de Boer May 30 '21 at 23:40
0

Have a look at Parsedown, https://parsedown.org/. It is exactly what you need.

0

Use this simple method:

$txt = " * first item in list";
$result = strpos($txt,"*");
//with *
if($result != false)
{
echo 'string replaced *  = '.str_replace("*","",$result);
}
$txt_1 = "first item in list";
$result_1 = strpos($txt_1,"*");
echo '<br>';
//without *
if($result_1 == false)
{
echo 'string without *';
} 
Faizan Ali
  • 297
  • 2
  • 9