1

I have a bunch of Nginx vhost files like this:

# This file was autogenerated by Puppet [ wordpress::vhost ]
# Any manual edit to this file will be automatically removed
# ©2016, DevOps team

server {
    listen 443 ssl;

    root /var/www/as888;
    index index.php;

    server_name wptraining-sdemo.mysysweb.com;
    ......
    ......

and I need to extract the value of the server_name directive (i.e. wptraining-sdemo.mysysweb.com in this case) from each file. I tried this, using preg_replace:

$host_dir = '/etc/nginx/sites-enabled';
$_pattern = '/^.*server_name (.*);$/U';

$_clients = scandir($host_dir);
foreach ( $_clients as &$client ) {
    if ( preg_match('/^as[0-9]{3}$/', $client, $matchs) ) {
        $wp_domain = preg_replace($_pattern, "$1", file("{$host_dir}/{$matchs[0]}"));
        echo "{$matchs[0]} => {$wp_domain[0]}";
    }
}

and I get the very 1st line of the file in return:

as888 => # This file was autogenerated by Puppet [ wordpress::vhost ]

if I use preg_grep instead:

$wp_domain = preg_grep($_pattern, file("{$host_dir}/{$matchs[0]}"));
print_r($wp_domain);

I get something like this:

Array
(
    [10] =>     server_name wptraining-sdemo.mysysweb.com;

)

which is rather strange to me, as I was expecting [0] (as there gonna be only one match) instead of [10]. Looks like it's creating an array with each line in the file.

what I'm doing wrong? And most importantly, what am I missing? I'm not very familiar with PHP and kind of lost in this. None of the help/posts, available in the net, worked. Basically, something similar to this: sed -n -e 's|^.*server_name \(.*\);$|\1|p' <file_name>, I believe. Any help would be greatly appreciated. Best!

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
MacUsers
  • 2,091
  • 3
  • 35
  • 56
  • `preg_grep` does not reset the indices, it returned the exact item with the index and value from the original array. – Wiktor Stribiżew Dec 07 '16 at 22:47
  • `preg_grep` was just a test to see what's actually being grepped. My actual goal is to extract the string between `server_name` and the trailing `;`. Thanks for solving the `preg_grep` mystery though. – MacUsers Dec 07 '16 at 22:53
  • Great, then why don't you do that exactly as you require? `preg_match('~server_name\h*(.*);~', $s, $match); echo $match[1];`? Actually, I think your approach will work if you add `m` modifier: `$_pattern = '/^.*server_name (.*);$/m';` - see [this demo](https://regex101.com/r/dsTF5T/1). – Wiktor Stribiżew Dec 07 '16 at 22:55
  • Have a look at [this demo](https://regex101.com/r/dsTF5T/1) – Wiktor Stribiżew Dec 07 '16 at 23:00
  • My PHP experience is practically a day and half long, so still catching up. Just figured out that `m` or `U` returns the correct value, if I specify `$wp_domain[10]` in the script, which is a very bad scripting to me as I've to relay on the correct line number, which can change any time. looking in `preg_match()` to figure out what does it actually do. – MacUsers Dec 07 '16 at 23:07
  • Thanks for the demo: very useful. – MacUsers Dec 07 '16 at 23:08
  • `preg_match` extracts the text matched with a regex expression. `preg_replace` replaces the match with the provided pattern. – Wiktor Stribiżew Dec 07 '16 at 23:11
  • What's the reason for the down voting? whoever did it may be a great programmer (and really really smart) but don't discourage others those who are learning. And always give the OP a reason. Really disappointing to see that when some us do that. – MacUsers Dec 13 '16 at 10:58
  • Hi, did my solution work for you? Or do you need a more specific solution? If the latter, I think the question might require clarifications - see, no one answered so far. – Wiktor Stribiżew Dec 13 '16 at 11:01
  • I had to move away for a bit from php but back again. your `preg_match()` suggestion actually worked very well and solved my issue. I'll put an update in the original post for others. – MacUsers Dec 13 '16 at 12:28

1 Answers1

1

You may use

preg_match('~server_name\h*(.*);~', $s, $match); 
echo $match[1];

See this regex demo

Details

  • server_name - a literal substring
  • \h* - 0+ horizontal whitespaces
  • (.*) - Group 1: any 0+ chars other than line break chars
  • ; - a ;.

Actually, I think your approach will work if you add m modifier:

$_pattern = '/^.*server_name (.*);$/m';

See this demo

*Details**:

  • ^.* - start of a line and then any 0+ chars other than line break chars
  • server_name - a literal substring
  • - space
  • (.*) - Group 1: any 0+ chars other than line break chars
  • ; - a ;.
  • $ - end of a line
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563