如何在PHP中获取"_"之前的字符串

3

我需要获取下划线 _ 之前的字符串,但是我的尝试没有正常工作。以下是存储在变量 $b 中的输入值列表:

vendor_code
vendor_name
hotel_name_0
hotel_room_type_0
hotel_in_date_0
...
vendor_code
vendor_name
hotel_name_N
hotel_room_type_N
hotel_in_date_N

这是我尝试过的方法:
$a = [
    'vendor_code',
    'vendor_name',
    'hotel_name_0',
    'hotel_room_type_0',
    'hotel_in_date_0'
];

foreach ($a as $b) {
    echo substr($b, 0, -(strlen(strrchr($b, '_')))), PHP_EOL;
}

代码几乎完美,但对于那些没有结尾的_N的情况失败了,因为它会删除原始字符串的一部分(请参见下面的输出)。
vendor 
vendor 
hotel_name 
hotel_room_type 
hotel_in_date

一个有效的输出应该如下所示:
vendor_code
vendor_name
hotel_name 
hotel_room_type 
hotel_in_date

这意味着我需要删除最后一个_N之后的所有内容。有人能给我一些建议吗?

请澄清一下,哪个 _ 需要作为分隔符?例如,hotel_in_date_0 应该返回去掉 0hotel_in_date,还是应该返回 hotelindate0 等等。 - Robert
@RobertC 我已将信息添加到原始帖子中,作为有效输出以及我想要删除的内容。 - ReynierPM
_N 总是一个数字吗? - Alexander Guz
@AlexanderGuz 是的,N 应该总是一个数字,但为了确保,如果需要的话,我可以对其进行检查。 - ReynierPM
5个回答

4

使用 preg_replace 函数仅需移除结尾的 _N 部分(如果存在):

...
foreach ($a as $word) {
    echo preg_replace("/_\d+$/", "", $word). PHP_EOL;
}

喜欢这个解决方案。我建议使用 preg_match,但这个更短。 - Alexander Guz
是的,我也喜欢这个,这就是为什么我接受了这个而不是你的,但你也有一票 :) - ReynierPM
比较所有能够完成相同任务的三个正则表达式,这个是最高效和最精确的,因为它只匹配结尾数字。 - Xorifelse

3
您可以尝试以下方法:
<?php

$a = [
    'vendor_code',
    'vendor_name',
    'hotel_name_0',
    'hotel_room_type_0',
    'hotel_in_date_0'
];

foreach ($a as $b) {
    $hasMatch = preg_match('/(.*)_\d+/', $b, $matches);
    if ($hasMatch) {
        echo $matches[1] . PHP_EOL;    
    } else {
        echo $b . PHP_EOL;
    }
}

输出:

vendor_code
vendor_name
hotel_name
hotel_room_type
hotel_in_date

2
你可以使用正则表达式来解决这个问题:
foreach ($a as $b) {
    if(preg_match('/(.*)(?:_\d)/', $b, $match)){
        echo "'$b' is a match and should be {$match[1]}\n";
    } else {
        echo "'$b' does not need a modification\n";
    }
}

结果为:

>     'vendor_code' does not need a modification
>     'vendor_name' does not need a modification
>     'hotel_name_0' is a match and should be hotel_name
>     'hotel_room_type_0' is a match and should be hotel_room_type
>     'hotel_in_date_0' is a match and should be hotel_in_date

0
你可以使用类似以下的代码:
$a = [
    'vendor_code',
    'vendor_name',
    'hotel_name_0',
    'hotel_room_type_0',
    'hotel_in_date_0'
];

$data = [];

foreach($a as $key) {
    $temp = explode('_', $key);
    if (is_numeric($temp[count($temp) - 1])) {
        unset($temp[count($temp) - 1]);
        $data[] = implode('_', $temp);
    } else {
        $data[] = $key;
    }
}

var_dump($data);

结果:

array (size=5)
  0 => string 'vendor_code' (length=11)
  1 => string 'vendor_name' (length=11)
  2 => string 'hotel_name' (length=10)
  3 => string 'hotel_room_type' (length=15)
  4 => string 'hotel_in_date' (length=13)

-1

试试这个:

foreach ($a as $b) {
    list($first, $second) = explode('_', $b, 2);
    echo implode(' ', [$first, $second, PHP_EOL]);
}

它没有输出预期的结果。 - Alexander Guz
这在这种情况下可能可行,但非常不灵活。 - Hutch Moore

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接