【问题标题】:Match string that contains two "needles"匹配包含两个“针”的字符串
【发布时间】:2026-01-13 05:35:01
【问题描述】:

我有一个看起来有点像这样的字符串

1: u:mads g:folk 2: g:andre u:jens u:joren

我需要的是一种方法(我猜是通过正则表达式)来获取例如 u:jens 和它之后的数字(1 或 2)。

我如何在 php 中解决这个问题(最好只有一个函数)?

【问题讨论】:

  • 搜索字符串是什么?
  • 我的问题总结得差不多了
  • 不,你想要模式,我想知道你在找什么。
  • 换句话说:为什么u:jens 而不是u:joreng:andre
  • 啊,真的没有理由,搜索字符串可以是其中任何一个(或多个)

标签: php regex string parsing pcre


【解决方案1】:

这将找到所有匹配项。如果您只需要第一个,请改用preg_match

<?php
$subject = '1: u:mads g:folk 2: g:andre u:jens u:joren 3: u:jens';
preg_match_all('#(\d+):[^\d]*?u:jens#msi', $subject, $matches);
foreach ($matches[1] as $match) {
    var_dump($match);
}
?>

【讨论】:

  • 附注:如果数字可能是字符串的有效字符,它将失败
  • 我假设它不是有效字符,因为样本不包含它,但这是非常正确的 - 了解您所做的假设,否则您将不断修正你的正则表达式。
  • 是的,我不想提你的解决方案是错误的,只是为不太了解正则表达式的人做一个注释。
  • 另请注意,[^\d] 会比.* 更快地失败
【解决方案2】:

您可以使用以下正则表达式:

(\d+):(?!.*\d+:.*).*u:jens

您要查找的数字位于第一个捕获组中。所以,如果你使用 PHP:

$matches = array();
$search = '1: u:mads g:folk 2: g:andre u:jens u:joren';
if (preg_match('/(\d+):(?!.*\d+:.*).*u:jens/', $search, $matches)) {
  echo 'Found at '.$matches[1]; // Will output "Found at 2"
}

【讨论】:

  • 如果您尝试搜索u:mads会怎样?
  • 好点:这个正则表达式只会匹配最后一个数字组中出现的键(例如,u:jens)。
【解决方案3】:

这将解析字符串并返回一个数组,其中包含找到搜索字符串的数字键:

function whereKey($search, $key) {
  $output = array();
  preg_match_all('/\d+:[^\d]+/', $search, $matches);

  if ($matches[0]) {
    foreach ($matches[0] as $k) {
      if (strpos($k, $key) !== FALSE) {
        $output[] = (int) current(split(':', $k));
      }
    }
  }

  return $output;
}

例如:

whereKey('1: u:mads g:folk 2: g:andre u:jens u:joren', 'u:jens')

...将返回:

array(1) { [0]=> int(2) }

【讨论】:

    最近更新 更多