Search code examples
phpregexvalidationpreg-matchmultiline

Validate multiline text so that all lines contain text with a strict, pipe-delimited format


Let's say we have an input that may consist of one or more lines of text and all lines must obey a strict format.

number|any character(s)|number

Ex.:

150|example.com/|2500
600|hello_world|1500

The characters in the middle may contain any characters, excluding whitespace. The numbers in the beginning and the end may consist of a single or multiple digits.

I want to check that all lines in the text obey the required format.

So far I came up with the following regex, but it's returning true even if only one line matches the format from above.

/[0-9]+\|.*?\|[0-9]/im

How can I adjust my pattern to validate the whole text and return true from preg_match()?


Solution

  • You can use

    /\A([0-9]+\|\S*\|[0-9]+)(?:\R(?1))*\z/
    

    See the regex demo. Details:

    • \A - start of string
    • ([0-9]+\|\S*\|[0-9]+) - Group 1: one or more digits, |, any zero or more nonwhitespace chars, as many as possible, |, and one or more digits
    • (?:\R(?1))* - zero or more repetitions of a line break and then Group 1 pattern
    • \z - end of string.

    See the PHP demo:

    $text = "150|google.com/|2500\n600|hello_world|1500";
    if (preg_match('~\A([0-9]+\|\S*\|[0-9]+)(?:\R(?1))*\z~', $text)){
        echo "Valid!";
    }
    // => Valid!