Search code examples
phparrayspattern-matchingsequence-diagramstring-math

Replacing a string in PHP


I am working on an app that gets text as input and gives Sequence Diagrams as output, something like Web Sequence Diagrams. So, for a default input, like Alice says Hi to Bob, the input is:

Alice -> Bob: Hi

The users can give any kind of inputs. The variations for the above line:

Alice -> Bob : Hi
Alice -> Bob :Hi
Alice -> Bob: Hi
Alice -> Bob:Hi
Alice ->Bob : Hi
Alice ->Bob :Hi
Alice ->Bob: Hi
Alice ->Bob:Hi
Alice-> Bob : Hi
Alice-> Bob :Hi
Alice-> Bob: Hi
Alice-> Bob:Hi
Alice->Bob : Hi
Alice->Bob :Hi
Alice->Bob: Hi
Alice->Bob:Hi

The other variations of the messages include the following arrows:

  • -
  • --
  • ->
  • -->
  • ->>
  • -->>

Even if I want to split the input based on -> and the :, it is difficult as these messages can come in any order. So, if I am giving something like:

Alice --> Bob: Hello
Bob -> Alice: See you!

At first I had restricted the users to give space compulsorily around the arrows. And after that, the count will be 3 and then the third array item is split using :. This is achieved using the below code:

$userInput = array_map('trim', explode("\r\n", trim($input)));
foreach ($userInput as $line) {
    $line = array_filter(array_map('trim', explode(" ", str_replace(array(":", ": "), " ", $line), 4)));

I replace the : with a space and split the string up to four characters with a space as the delimiter. Am I doing rightly, as this doesn't work if the spaces given are like above and when all types of arrows are given by the user, this method doesn't work. Please guide me.


Solution

  • Try using regular expressions and preg_match (http://www.php.net/preg_match). It will make your life a lot easier.

    Regular Expression Pattern:

    /(\w+)\s*\-+>{1,2}\s*(\w+)\s*:\s*(\w+)/i
    

    Breakdown:

    (\w+)  <- Match and return 1 or more characters
    \s*    <- Match 0 or more white space characters
    (\-+>{1,2}) <- Match and return 1 or more "-" characters followed by 1 or 2 ">" characters
    

    Source:

    <?php
    foreach ($userInput as $line) {
        $matches = array();
        preg_match('/(\w+)\s*(\-+>{1,2})\s*(\w+)\s*:\s*(\w+)/i', $line, $matches);
        echo $matches[1] . "\n"; // Alive
        echo $matches[2] . "\n"; // --> or -> or --->
        echo $matches[3] . "\n"; // Bob
        echo $matches[4] . "\n"; // Hi
    }