【问题标题】:How to get specific part of string in php using regex?如何使用正则表达式在php中获取字符串的特定部分?
【发布时间】:2015-05-05 13:59:38
【问题描述】:

我在一个数组中有产品名称,

$productArr = array("Dell Inspiron 15 3521 Laptop CDC/ 2GB/ 500GB/ Linux Black Matte Textured Finish","Dell Inspiron 15 3521 Laptop CDC/ 4GB/ 500GB/ Win8 Black","Nikon D90 DSLR (Black) with AF-S 18-105mm VR Kit Lens");

我想得到类似的输出,

$productModArr = array("Dell Inspiron 15 3521","Dell Inspiron 15 3521","Nikon D90")

然后我需要删除重复的字符串,

$productModArr = array("Dell Inspiron 15 3521","Nikon D90")

我尝试了substrstrpos,但这些都不适用于我的情况。

【问题讨论】:

  • 那么您必须定义名称何时结束。
  • 在第一次播放中插入笔记本电脑名称时添加分隔符,然后使用该分隔符剪切字符串。否则,您可以使用字典方法,但它无法处理您未填写数组的笔记本电脑。
  • 我建议第一部分使用 RegEx php.net/manual/en/function.preg-match.php,第二部分使用 array_unique php.net/manual/de/function.array-unique.php
  • @Rizier123 @ Answers_Seeker 谢谢,但我是通过提要获得产品名称的,所以我必须使用修改后的产品名称创建产品类别。
  • @JaGo 谢谢你,你能帮我完成第一部分吗,我无法得到确切的 preg_match 因为我的产品名称没有特定的结尾。

标签: php arrays regex string


【解决方案1】:

您可以使用下面的自定义 PHP 函数(使用正则表达式)来生成您在上面的问题中概述的所需输出。

根据您希望在产品 Feed 中匹配的模式,您可能需要稍微调整正则表达式匹配模式。

function getProductNames ($productArr) {

$countproductArr = count($productArr);
for ($i = 0; $i < $countproductArr; $i++) {
$productModArr[] = preg_replace('/^([^0-9]*)([0-9]+)(\s[0-9]+)?(.*)/', '$1$2$3', $productArr[$i]);
}

$productModArr = array_unique($productModArr);
$productModArr = array_values($productModArr);
return $productModArr;
}

$productModArr = getProductNames($productArr);

正则表达式的解释:

/ [... match goes here... ] /

^ - 比赛开始

([^0-9]*) - [第一个捕获组] 任意非数字字符,任意次数

([0-9]+) - [第二个捕获组] 任意数字字符,从 1 到任意次数

(\s[0-9]+)? - [第三个(可选)捕获组] 后跟任意数字字符的空格,从 1 到任意次数

(.*) - 在第三个(可选)捕获组之后任意次数的任意数量的字符

=======

更新

将上述函数中的相关行替换为:

$productModArr[] = preg_replace('/^([^0-9]*)([^\s]+)(\s[A-Z]?[0-9]+)?(.*)/', '$1$2$3', $productArr[$i]);

在更多情况下可能更适合产品名称和 odel 编号。

【讨论】:

  • 如果我在阵列中也有这些类型的字符串,Toshiba Satellite L50-B I3010,Lenovo Z50-70 Ideapad 我可以在模式中添加什么?
  • 此时,您需要给我们一些正式的描述,说明您希望每个字符串结束的位置。例如,为什么要让 Toshiba 字符串在 I3010 之后结束,而不是在 L50-B 之后?为什么你希望联想字符串在 Ideapad 之后结束,而不是在 Z50-70 之后?您希望在每个字符串中保留的元素与您希望丢弃的元素有什么区别?
  • 对不起,我不需要ideapad。实际上我正在尝试获取带有型号的产品名称。
  • 您的脚本在大多数情况下都可以正常工作,但如果我有 HP 15-g221AU(笔记本)、Acer Aspire E5-571-56UR 笔记本等产品,它可以匹配 HP 15、Acer Aspire仅限 E5。我需要完整的型号,例如 Acer Aspire E5-571-56UR。
  • 这应该是可能的。让我绞尽脑汁,看看我能为你想出什么……
【解决方案2】:

这将适用于您的 3 个示例,但由于此类产品名称没有标准,因此格式不同的情况可能很多。

$productArr = array("Dell Inspiron 15 3521 Laptop CDC/ 2GB/ 500GB/ Linux Black Matte Textured Finish","Dell Inspiron 15 3521 Laptop CDC/ 4GB/ 500GB/ Win8 Black","Nikon D90 DSLR (Black) with AF-S 18-105mm VR Kit Lens");
 $newArr = array();
foreach($productArr as $str){
  $pattern = "/[a-zA-Z\ ]*[ A-Z]?[0-9 ]*/";
  preg_match($pattern, $str,$match);
  $newArr[] = $match[0];
}

$result = array_unique($newArr);
print_r($result);

【讨论】:

  • 谢谢。东芝Satellite L50-B I3010,联想Z50-70,我也需要此类字符串的帮助。
【解决方案3】:

在我的测试字符串组中,我包含了您在问题和/或 cmets 中提到的所有示例字符串。

我的模式将假设您希望保留从每个字符串的开头到包含数字的第一个空格分隔的字符串序列结尾的子字符串。这很难用简单的英语来解释,就像写成正则表达式一样。 :)

模式说明:Pattern & Replacement Demo

/                           #opening pattern delimiter
^                           #match from the start of the string
\D*                         #match zero or more characters that are not a digit
(?: [a-z\d-]*\d[a-z\d-]*)+  #match zero or more letters,digits,hyphens followed by a digit followed by zero or more letters,digits,hyphens
\K                          #restart the fullstring match (to avoid using a capture group)
.*                          #match remainder of the string
/                           #closing pattern delimiter
i                           #case-insensitive pattern modifier

代码:(PHP Demo)

$productArr=[
    'Dell Inspiron 15 3521 Laptop CDC/ 2GB/ 500GB/ Linux Black Matte Textured Finish',
    'Dell Inspiron 15 3521 Laptop CDC/ 4GB/ 500GB/ Win8 Black',
    'Nikon D90 DSLR (Black) with AF-S 18-105mm VR Kit Lens',
    'Toshiba Satellite L50-B I3010',
    'Lenovo Z50-70',
    'Apple',
    'HP 15-g221AU (Notebook)',
    'Acer Aspire E5-571-56UR Notebook'
];
var_export(array_flip(array_flip(preg_replace('/^\D*(?: [a-z\d-]*\d[a-z\d-]*)+\K.*/i','',$productArr))));

输出:

array (
  1 => 'Dell Inspiron 15 3521',
  2 => 'Nikon D90',
  3 => 'Toshiba Satellite L50-B I3010',
  4 => 'Lenovo Z50-70',
  5 => 'Apple',
  6 => 'HP 15-g221AU',
  7 => 'Acer Aspire E5-571-56UR',
)

附言我正在使用array_flip() 的双重调用,因为:

  1. 它不会损害您的价值观。
  2. 它的运行速度比array_unique() 快。
  3. 它允许将整个方法链接在一行中。

(如果您愿意,欢迎您使用array_unique() -- 相同,相同。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-11
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 2021-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多