正则表达式在=后获得值

I'm trying to get the values ad.test.com and 768 from the string "adress=ad.test.com port=768" with this regex but it doesn't work :/

$res = preg_split("/^adresse=([a-z]).*port=([0-9]{3})/", $test) ; 

This should capture the 2 data points you want:

^adress=([a-z.]+).*port=([0-9]{3})

You also want to use this with preg_match, not preg_split.

preg_match('/^adress=([a-z.]+).*port=([0-9]{3})/s', 'adress=ad.test.com
 port=768', $match);
echo $match[1] . ' ' . $match[2];

Demo: https://3v4l.org/Ih929

Notes on why your regex failed:

  1. Character class missing ., and the character class wasn't quantified.
  2. adress is in your string but you are looking for addresse in your regex
  3. . doesn't match new lines unless the s modifier is used.

Regex demo: https://regex101.com/r/3MSiDh/1/

A more accurate regex that won't require s modifier:

^adress=([a-z.]+?)\s*port=(\d{3})

Demo 2: https://regex101.com/r/3MSiDh/3/

First optimisation, close to your expression:

preg_match('/\badress=([a-z\.]*)\s+port=(\d*)/',$string,$matches)

It is slightly more generic. You do not want to match on 'badaddress' for example, that is what the \b is for, you might get more than 3 digits for the port, etc, I use \d in stead of [0-9].

But this regular expression is very strict on the input: the order is fixed, the location of spaces is limited, you can't have any unknowns. To resolve that, I would match on parameter/value pairs, and then act upon each of these pairs. Further, named matching reduces mistakes with parentheses and future evolutions of the regular expression.

The parameter/value pair match can look like this:

preg_match_all('/\b(?P<param>[^\d\s]\S*)\s*=\s*(?P<value>\S*)(?:\s|$)/m',$string,$matches)

This provides $matches['param'] and $matches['value']. The example below then walks through this list to find the known parameters and check the validity of their values in order to provide some error messages when appropriate.

The code below shows complete code with some test strings. You can check it out here.

/** Some strings to test our code */
$testStrings=[
    "adress=example.com port=464",
    "adress =example.com
port=4645",
    "port=1  protocol=https adress= example.com",
];
/** Test for each string */
foreach($testStrings as $string) {
    print "

TESTING:'".escapeshellarg($string)."'
";

    /** First method - does not match them all */
    if(preg_match('/\badress=([a-z\.]*)\s+port=(\d*)/',$string,$matches)) {
        print "Matched {$matches[1]}:{$matches[2]}
";
    }

    /** Second method - get param/value pairs first, then check them */
    if(preg_match_all('/\b(?P<param>[^\d\s]\S*)\s*=\s*(?P<value>\S*)(?:\s|$)/m',$string,$matches)) {
        //var_dump($matches); // Uncomment to see the raw data.
        $i=0;  // We need an index.
        foreach($matches['param'] as $param) {
            $value=$matches['value'][$i]; // Put value in local $value
            $i++;
            switch($param) { // Find parameters we know, complain if needed.
                case "adress":
                    print "ADDRESS IS $value
";
                    break;
                case "port":
                    if(($result=preg_match('/^\d{3}$/',$value))) {
                        var_dump($result);
                        print "PORT IS $value
";
                    } else {
                        print "PORT MUST HAVE EXACTLY 3 DIGITS - Got: $value
";
                    }
                    break;
                default:
                    print "UNKNOWN PARAMETER $param=$value
";
            }
        }
    }
}