捕获字符串中方括号占位符内不确定数量的分隔值

发布于 2024-10-31 18:20:03 字数 553 浏览 7 评论 0原文

我有以下正则表达式:

\[([^ -\]]+)( - ([^ -\]]+))+\]

此匹配成功:

[abc - def - ghi - jkl]

但匹配是:

Array
(
    [0] => [abc - def - ghi - jkl]
    [1] => abc
    [2] =>  - jkl
    [3] => jkl
)

我需要的是这样的:

Array
(
    [0] => [abc - def - ghi - jkl]
    [1] => abc
    [2] =>  - def
    [3] => def
    [4] =>  - ghi
    [5] => ghi
    [6] =>  - jkl
    [7] => jkl
)

我可以在 C# 中查看组“捕获”来做到这一点。我怎样才能在 PHP 中做到这一点?

I have the following regex:

\[([^ -\]]+)( - ([^ -\]]+))+\]

This match the following successfully:

[abc - def - ghi - jkl]

BUT the match is:

Array
(
    [0] => [abc - def - ghi - jkl]
    [1] => abc
    [2] =>  - jkl
    [3] => jkl
)

What I need is something like this:

Array
(
    [0] => [abc - def - ghi - jkl]
    [1] => abc
    [2] =>  - def
    [3] => def
    [4] =>  - ghi
    [5] => ghi
    [6] =>  - jkl
    [7] => jkl
)

I'm able to do that in C# looking at the groups "captures". How can I do that in PHP?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

南街九尾狐 2024-11-07 18:20:03

这不是正则表达式的工作。匹配\[([^\]]*)\],然后爆炸通过" - "第一次捕获。

<?php                                                                       
  $str = "[abc - def - ghi - jkl]";
  preg_match('/\[([^\]]*)\]/', $str, $re);
  $strs = explode(' - ', $re[1]);
  print_r($strs);
?>

This is not the job for the regexp. Match against \[([^\]]*)\], then explode the first capture by the " - ".

<?php                                                                       
  $str = "[abc - def - ghi - jkl]";
  preg_match('/\[([^\]]*)\]/', $str, $re);
  $strs = explode(' - ', $re[1]);
  print_r($strs);
?>
给我一枪 2024-11-07 18:20:03

假设示例字符串中的标记从不包含空格,并且是字母数字:

<?php
    $pattern = "/([\w|\d])+/";
    $string = "[abc - 123 - def - 456 - ghi - 789 - jkl]";
    preg_match_all($pattern, $string, $matches);
    print_r($matches[0]);
?>

输出:

Array
(
    [0] => abc
    [1] => 123
    [2] => def
    [3] => 456
    [4] => ghi
    [5] => 789
    [6] => jkl
)

Assuming the tokens in your sample string never contain spaces, and are alphanumeric:

<?php
    $pattern = "/([\w|\d])+/";
    $string = "[abc - 123 - def - 456 - ghi - 789 - jkl]";
    preg_match_all($pattern, $string, $matches);
    print_r($matches[0]);
?>

Output:

Array
(
    [0] => abc
    [1] => 123
    [2] => def
    [3] => 456
    [4] => ghi
    [5] => 789
    [6] => jkl
)
一影成城 2024-11-07 18:20:03

SPL preg_match_all 将返回从 < 的索引 1 开始的正则表达式组代码>$matches 变量。如果您只想获取第二组,您可以使用 $matches[2] 例如。

语法:

$matches = array(); 
preg_match_all(\
    '/(He)\w+ (\w+)/', 
    "Hello world\n Hello Sunshine", 
    $matches
); 
var_dump($matches);

结果:

array(3) {
  [0] =>
  array(2) {
    [0] =>
    string(11) "Hello world"
    [1] =>
    string(14) "Hello Sunshine"
  }
  [1] =>
  array(2) {
    [0] =>
    string(2) "He"
    [1] =>
    string(2) "He"
  }
  [2] =>
  array(2) {
    [0] =>
    string(5) "world"
    [1] =>
    string(8) "Sunshine"
  }
}

PS 此答案是在通过 Google 搜索定向到此处后针对问题标题的上下文发布的。这是我在搜索该主题时感兴趣的信息。

SPL preg_match_all will return regex groups starting on index 1 of the $matches variable. If you want to get only the second group you can use $matches[2] for example.

Syntax:

$matches = array(); 
preg_match_all(\
    '/(He)\w+ (\w+)/', 
    "Hello world\n Hello Sunshine", 
    $matches
); 
var_dump($matches);

Result:

array(3) {
  [0] =>
  array(2) {
    [0] =>
    string(11) "Hello world"
    [1] =>
    string(14) "Hello Sunshine"
  }
  [1] =>
  array(2) {
    [0] =>
    string(2) "He"
    [1] =>
    string(2) "He"
  }
  [2] =>
  array(2) {
    [0] =>
    string(5) "world"
    [1] =>
    string(8) "Sunshine"
  }
}

P.S. This answer is posted for the context of the question title after being directed here by a Google search. This was the information I was interested in when searching for this topic.

等数载,海棠开 2024-11-07 18:20:03

要将匹配项分组,请使用括号。 EG:

$string = 'bob';
preg_match('/bob/', $string, $matches);

$matches 将是 ['bob']

preg_match('/(b)(o)(b)/', $string, $matches);

$matches 将是 ['bob','b','o ','b']

To group your matches, use parenthesize. EG:

$string = 'bob';
preg_match('/bob/', $string, $matches);

$matches will be ['bob']

preg_match('/(b)(o)(b)/', $string, $matches);

$matches will be ['bob','b','o','b']

我不会写诗 2024-11-07 18:20:03

要匹配方括号占位符内不确定数量的分隔值,请匹配占位符的开头并向前查找以验证占位符的其余部分,或者从上一个匹配以 \G 元字符后跟定界子字符串;那么你就可以匹配所寻求的值。

代码:(演示)

$text = 'foo [abc - def - ghi - jkl] bar';
$regex = <<<REGEX
/                  
(?:                #start a non-capturing group
   \[              #match a left square brace
   (?=[a-z -]+])   #lookahead for the completion of a valid placeholder expression
   |               #or
   \G(?!^)         #continue from end position of last match and not the start of the string
   \s-\s           #match a whitespace, hyphen then a whitespace
)                  #close the non-capturing group
\K                 #forget any matched characters up to this position
[a-z]+             #match one or more lowercase ascii letters
/x
REGEX;
if (preg_match_all($regex, $text, $match)) {
    var_export($match[0]);
}

输出:

array (
  0 => 'abc',
  1 => 'def',
  2 => 'ghi',
  3 => 'jkl',
)

To match an indeterminant number of delimited values inside of a square-braced placeholder, either match the start of the placeholder and lookahead to validate the remainder of the placeholder or match from where the previous match ended with the \G metacharacter followed by the delimiting substring; then you can just match the sought values.

Code: (Demo)

$text = 'foo [abc - def - ghi - jkl] bar';
$regex = <<<REGEX
/                  
(?:                #start a non-capturing group
   \[              #match a left square brace
   (?=[a-z -]+])   #lookahead for the completion of a valid placeholder expression
   |               #or
   \G(?!^)         #continue from end position of last match and not the start of the string
   \s-\s           #match a whitespace, hyphen then a whitespace
)                  #close the non-capturing group
\K                 #forget any matched characters up to this position
[a-z]+             #match one or more lowercase ascii letters
/x
REGEX;
if (preg_match_all($regex, $text, $match)) {
    var_export($match[0]);
}

Output:

array (
  0 => 'abc',
  1 => 'def',
  2 => 'ghi',
  3 => 'jkl',
)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文