RegEx正则表达式获取ID

Given a string of the following:

  • [download id="1"]
  • [download id="1" attr=""]
  • [download attr="" id="1"]
  • [download attr="" id="1" attr=""]

ID is always a number. I need a regular expression that will always give me that number to be used via PHP preferably demonstrated via http://www.solmetra.com/scripts/regex/index.php.

try this one:

/\[download.*?id=\"(\d+)\"/

Function called:

preg_match_all('/\[download.*?id=\"(\d+)\"/', '{{your data}}', $arr, PREG_PATTERN_ORDER);
preg_match_all('/id="(\d+)"/', $data, $matches);

Assuming that you will always have one id field and that it will always be enclosed within quotes ("), you can try something like a regular expression like so: id="(\d+)". This will capture the number and put it in a group. You can take a look here to see how you can then access these groups.

As it has been suggested, should you want to match more fields, I would recommend you drop regular expressions and find something which is able to parse the string you are passing.

This would also be a solution

\[download[^\]]*id="(\d*)

You find your result in capturing group 1

See it here on Regexr

\[download match "[download"

[^\]]* is a negated character class, matches everything that is not a "]" (o or more times)

id=" matches "id="" literally

(\d*) is a capturing group that matches 0 or more digits, you can change the * to a + to match one or more.

What absolutely every Programmer should know about regular expressions

you can use easily ini files and not regex in needed, for example:

test.ini

[download]
id=1
attr = ""
[download2]
id=2
attr = "d2"

and index.php

$ini = parse_ini_file('test.ini', true);
print_r($ini);

This is my solution:

<?php

    $content =
<<<TEST
[download id="1"]
[download id="2" attr=""]
[download attr="" id="3"]
[download attr="" id="4" attr=""]
TEST;

    $pattern = '/\[download.*[ ]+id="(?P<id>[0-9]+)".*\]/u';

    if (preg_match_all($pattern, $content, $matches))
        var_dump($matches);

?>

Works with a single line input (read in $matches['id'][0]) or with a multiple lines input (like the example, iterating on $matches['id'] array).

Note:

  • Don't use preg_match with start ^ and end $ delimiters, use instead preg_match_all without delimiters
  • Don't use the "s" PCRE_DOTALL modifier
  • Use the "i" modifier if you want the regex works with both "download" or "DOWNLOAD"
  • Use the "u" modifier if the input is an UTF-8 encoded string

http://it.php.net/manual/en/function.preg-match-all.php

http://it.php.net/manual/en/reference.pcre.pattern.modifiers.php

The above example will output this:

array(3) {
  [0]=>
  array(4) {
    [0]=>
    string(17) "[download id="1"]"
    [1]=>
    string(25) "[download id="2" attr=""]"
    [2]=>
    string(25) "[download attr="" id="3"]"
    [3]=>
    string(33) "[download attr="" id="4" attr=""]"
  }
  ["id"]=>
  array(4) {
    [0]=>
    string(1) "1"
    [1]=>
    string(1) "2"
    [2]=>
    string(1) "3"
    [3]=>
    string(1) "4"
  }
  [1]=>
  array(4) {
    [0]=>
    string(1) "1"
    [1]=>
    string(1) "2"
    [2]=>
    string(1) "3"
    [3]=>
    string(1) "4"
  }
}

So, you can read the ID attributes looping on $matches['id'] array :)