0

I'm trying to parse something like this

{%github user/repo %}

Into

<a href="https://github.com/user/repo">Repo</a>

This method also should be secure ex: Look below my function.

function parseliquid($string)
{
    $randhashtoreplace = md5(rand(0, 9999));
    $regexp = '/\{%github (.*?)%\}/';
    $str = preg_replace($regexp, $randhashtoreplace, $string);

    preg_match($regexp, $string, $matches);
    return $matches;
}


var_dump(parseliquid("## Hello {%github isn't/safe {%github repo/user %} %}"));

Now the expected output is

array(2) {
  [0]=>
  string(41) "{%github isn't/safe {%github repo/user %}"
  [1]=>
  string(9) "repo/user"
}

but the output that comes is

array(2) {
  [0]=>
  string(41) "{%github isn't/safe {%github repo/user %}"
  [1]=>
  string(30) "isn't/safe {%github repo/user "
}

Now what have I done wrong?

4
  • 2
    "Now what have I done wrong?" choosing regular expression to parse nested expressions (they aren't suited for that, see the regex HTML or JSON parsing problems). You need to either write a proper parser or use an existing one Commented Nov 12, 2021 at 10:36
  • @Cid so I can use a lib. Can you tell me some of those? Commented Nov 12, 2021 at 10:38
  • I'm sure if you type in your favorite search engine "liquid php parser", you'll find lots of packages Commented Nov 12, 2021 at 10:40
  • Ok thanks @Cid . Commented Nov 12, 2021 at 10:42

1 Answer 1

1

You can try this code

<?php

function getRepositoryNames(string $value): array
{
    \preg_match_all('/\{\%github\s(?<repo>[a-z0-9-_]+\/[a-z0-9-_]+)\s+/', $value, $matched);

    if (!isset($matched['repo'])) {
        return [];
    }

    return \array_map(static fn ($item) => 'https://github.com/'.$item, $matched['repo']);
}

\var_dump(getRepositoryNames('{%github isnt/safe {%github repo/user1-test %}'));
/*
 array(2) {
  [0]=>
  string(28) "https://github.com/isnt/safe"
  [1]=>
  string(34) "https://github.com/repo/user1-test"
}
 */

Documentation:

https://www.php.net/manual/en/function.preg-match.php - Use Example #4

Tested Regex you can this https://regexr.com/

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you! and why did you use \ s?
\s it's short from space If you use \s regex try find one space ` ` another \s+ one or more spaces
@ŕ̷͉ge̸ḓ̶̅i̷t regex-cheatsheet

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.