PHP正则表达式:在另一个表达式中多次匹配整个表达式 摘要

PHP正则表达式:在另一个表达式中多次匹配整个表达式 摘要,php,regex,Php,Regex,要匹配的示例字符串: 测试前1测试2测试3测试后 需要正则表达式: 之前(表达)之后 详细说明 我对PHP中的正则表达式有一个问题,即使经过广泛的搜索和无数次的尝试,我仍然无法正确使用它,这非常令人愤怒 这是我要分析的字符串: “地点”:[{“id”:1204,“姓名”:“房间1”},{“id”:1205,“姓名”:“房间” 2“},{“id”:1206,“姓名”:“房间3”},{“id”:1207,“姓名”:“房间 4“},{“id”:1208,“name”:“Room 5”},{“id”:

要匹配的示例字符串:

测试前1测试2测试3测试后

需要正则表达式:

之前(表达)之后


详细说明 我对PHP中的正则表达式有一个问题,即使经过广泛的搜索和无数次的尝试,我仍然无法正确使用它,这非常令人愤怒

这是我要分析的字符串:

“地点”:[{“id”:1204,“姓名”:“房间1”},{“id”:1205,“姓名”:“房间” 2“},{“id”:1206,“姓名”:“房间3”},{“id”:1207,“姓名”:“房间 4“},{“id”:1208,“name”:“Room 5”},{“id”:1209,“name”:“Room” 6“},{“id”:1210,“name”:“Room 7”},{“id”:1211,“name”:“Room 1”}]

格式化以提高可读性

"places":[
  {
    "id":1204,
    "name":"Room 1"
  },
  {
    "id":1205,
    "name":"Room 2"
  },
  {
    "id":1206,
    "name":"Room 3"
  },
  {
    "id":1207,
    "name":"Room 4"
  },
  {
    "id":1208,
    "name":"Room 5"
  },
  {
    "id":1209,
    "name":"Room 6"
  },
  {
    "id":1210,
    "name":"Room 7"
  },
  {
    "id":1211,
    "name":"Room 1"
  }
]
使用preg\u match\u all时的结果应为以下数组:

Array
(
  [0] => Array
  (
    [0] => {"id":1204,"name":"Room 1"}
    [1] => {"id":1205,"name":"Room 2"}
    [2] => {"id":1206,"name":"Room 3"}
    [3] => {"id":1207,"name":"Room 4"}
    [4] => {"id":1208,"name":"Room 5"}
    [5] => {"id":1209,"name":"Room 6"}
    [6] => {"id":1210,"name":"Room 7"}
    [7] => {"id":1211,"name":"Room 1"}
  )
  [1] => Array
  (
    [0] => 1204
    [1] => 1205
    [2] => 1206
    [3] => 1207
    [4] => 1208
    [5] => 1209
    [6] => 1210
    [7] => 1211
  )
  [2] => Array
  (
    [0] => Room 1
    [1] => Room 2
    [2] => Room 3
    [3] => Room 4
    [4] => Room 5
    [5] => Room 6
    [6] => Room 7
    [7] => Room 1
   )
)
现在我连续两次使用preg\u match\u all,如下所示:

preg_match_all('/\"places\"\:\[(.*)\]/', $places_string, $raw_string_to_analyse);
preg_match_all('/\{\"id\"\:([0-9]*),\"name\"\:\"(.*?)\"\}/', $places, $middle_part);
现在我有中间部分:

{“id”:1204,“name”:“Room 1”},{“id”:1205,“name”:“Room 2“},{“id”:1206,“姓名”:“房间3”},{“id”:1207,“姓名”:“房间 4“},{“id”:1208,“name”:“Room 5”},{“id”:1209,“name”:“Room” 6“},{“id”:1210,“name”:“Room 7”},{“id”:1211,“name”:“Room 1”}

现在我提取的信息如下:

preg_match_all('/\"places\"\:\[(.*)\]/', $places_string, $raw_string_to_analyse);
preg_match_all('/\{\"id\"\:([0-9]*),\"name\"\:\"(.*?)\"\}/', $places, $middle_part);
现在我有了我需要的信息

不幸的是,我无法将这两个表达式组合为一个表达式,如下所示:

preg_match_all('/\"places\"\:\[(.*)\]/', $places_string, $raw_string_to_analyse);
preg_match_all('/\{\"id\"\:([0-9]*),\"name\"\:\"(.*?)\"\}/', $places, $middle_part);
[MATCH_BEFORE][MATCH_IN_MIDDLE][MATCH_IN_BEFORE][MATCH_IN_MIDDLE]{根据需要经常匹配}[MATCH_AFTER]

因此,我必须将第一个表达式中的(.)替换为{“id\”:([0-9]),“name\”:“(.*?”),, (注意末尾的可选逗号)

我无法找到一种方法将内部表达式括在括号中(或任何需要的地方),并让它匹配一定的次数(*)


我希望有人能帮助我,因为现在我很恼火,我不知道怎么做。

这个字符串实际上是一个json字符串。也就是说,您只需要对其进行解码并对结果进行一些数据提取:

$string = '{"places":[{"id":1204,"name":"Room 1"},{"id":1205,"name":"Room 2"},{"id":1206,"name":"Room 3"},{"id":1207,"name":"Room 4"},{"id":1208,"name":"Room 5"},{"id":1209,"name":"Room 6"},{"id":1210,"name":"Room 7"},{"id":1211,"name":"Room 1"}]}';

$data = json_decode($string, true);
$ids = array_column($data['places'], 'id');
$names = array_column($data['places'], 'name');
$json = <<<JSON
{"places":[{"id":1204,"name":"Room 1"},{"id":1205,"name":"Room 2"},{"id":1206,"name":"Room 3"},{"id":1207,"name":"Room 4"},{"id":1208,"name":"Room 5"},{"id":1209,"name":"Room 6"},{"id":1210,"name":"Room 7"},{"id":1211,"name":"Room 1"}]}
JSON;

if (preg_match_all('~(?:\G,|\{"places":\[)\K\{"id":(\d+),"name":"([^"]+)"}~', $json, $matches)) {
    unset($matches[0]);  // throw away the fullstring matches subarray
    var_export($matches);
}
后期编辑

为了获得相同的结果,但是对于正则表达式,您可以使用的唯一正则表达式是
/{“id”:([0-9]+),“name”:([\w\s]+)”}/
。这些匹配将完全符合您在问题中的预期:

preg_match_all('/{"id":([0-9]+),"name":"([\w\s]+)"}/', $string, $matches);

echo '<pre>';
var_dump($matches);
echo '</pre>';
如果您有多个关键点,并且只需要对位置进行匹配,则首先必须提取所有位置值,并对结果执行preg_match_all:

$string = '{"places":[{"id":1204,"name":"Room 1"},{"id":1205,"name":"Room 2"},{"id":1206,"name":"Room 3"},{"id":1207,"name":"Room 4"},{"id":1208,"name":"Room 5"},{"id":1209,"name":"Room 6"},{"id":1210,"name":"Room 7"},{"id":1211,"name":"Room 1"}]}';

$data = json_decode($string, true);
$ids = array_column($data['places'], 'id');
$names = array_column($data['places'], 'name');
$json = <<<JSON
{"places":[{"id":1204,"name":"Room 1"},{"id":1205,"name":"Room 2"},{"id":1206,"name":"Room 3"},{"id":1207,"name":"Room 4"},{"id":1208,"name":"Room 5"},{"id":1209,"name":"Room 6"},{"id":1210,"name":"Room 7"},{"id":1211,"name":"Room 1"}]}
JSON;

if (preg_match_all('~(?:\G,|\{"places":\[)\K\{"id":(\d+),"name":"([^"]+)"}~', $json, $matches)) {
    unset($matches[0]);  // throw away the fullstring matches subarray
    var_export($matches);
}

preg_match('/(?首先,让我明确地宣布,您不应该通过尝试使用正则表达式解析有效的json字符串的值来滥用它

Matei涉及
json\u decode()
array\u column()
的解决方案正是我编写代码的方式,也应该是您编写代码的方式,因为它是直接的,并且采用了最佳实践(假设json是有效的)

对于不是json但希望执行全局重复匹配的理论/未列出的数据…是的,您可以通过利用
\G
的魔力执行单个、巧妙的正则表达式函数调用

一些文档有助于理解如何继续匹配重复序列

(使用json数据)

代码:()


为什么不使用json_decode来获得一个更容易处理的数组或对象呢?我现在将使用json_decode来解决这个特殊问题,但我仍然需要知道如何将正则表达式放入另一个正则表达式中,以进行未知次数的匹配,因为我有其他(非json)正则表达式要匹配的字符串。感谢您的解决方案,它实际上比我想象的要简单。我现在将以这种方式使用它。但是,我仍然对如何将正则表达式放入另一个正则表达式中以进行未知次数的匹配感兴趣,因为我必须处理很多问题,并且无法找到解决方案到目前为止。感谢您的更新。我有多个“组”,其中包含“id”和“名称”,而不仅仅是“位置”。我如何选择“位置”把其他的都排除在外?谢谢。看起来我必须像你在第二次编辑中那样在两个单独的比赛中完成。我觉得很遗憾,不可能把它们合并成一个大比赛,这会让事情变得更容易。谢谢你的详细解释和例子。看起来我需要多考虑一下从现在起,我们就把这个框放在外面。很少有开发人员知道regex中的
\G
字符。正如我之前所说,你不应该在有效的json上使用这个字符。这个模式绝对是不必要的卷积。只有当你的字符串不是json时,才应该考虑这个问题。很乐意帮忙。因为它不是作为json文件出现在我面前的,所以我甚至没有考虑过它nk正在考虑以这种方式解析它。将来,我会后退一步,稍微看看侧面,以找到其他解决方案。