【问题标题】:PHP - Conditional extraction of a string from within another?PHP - 有条件地从另一个字符串中提取字符串?
【发布时间】:2013-05-28 11:04:35
【问题描述】:

我需要一些关于 PHP 的帮助,因为我对它很陌生。

我有这些来自某个位置的字符串集,我需要有条件地从中提取一个字符串子集,只要它存在。

设置:

我得到的每个字符串都有这些Attributes,每个Attribute 都有一些Values。所有Attributes 都是可选的,所有Attributes 都可以有可变数量的值。

这些字符串的模式是这样的:

... Attribute Name: Attribute Values Attribute Name: Attribute Values ...

例如,这里有一些示例字符串:

Attribute A: Value 1, Value 2 Attribute B: Value 3, Value 4, Value 5, Value 6 Attribute C: Value 7, Attribute D: Value 8, Value 9

Attribute A: Value 1, Value 2, Value 3 Attribute B: Value 4, Value 5 Attribute C: Value 6, Value 7, Value 8, Attribute E: Value 9, Value 10, Value 11

Attribute B: Value 1, Value 2, Value 3 Attribute C: Value 4 Attribute D: Value 5, Value 6, Value 7, Value 8 Attribute E: Value 9, Value 10

请注意,某些字符串缺少一些 Attributes,并且所有 Attributes 旁边可以列出可变数量的 Values

问题:

我想提取Attribute D 的所有值,只要ValuesAttribute D 存在。

例如..

输入这个字符串:

Attribute A: Value 1, Value 2 Attribute B: Value 3, Value 4, Value 5, Value 6 Attribute C: Value 7, Attribute D: Value 8, Value 9

我应该得到这个输出:Value 8, Value 9

输入这个字符串:

Attribute A: Value 1, Value 2, Value 3 Attribute B: Value 4, Value 5 Attribute C: Value 6, Value 7, Value 8, Attribute E: Value 9, Value 10, Value 11

我应该得到这个输出:一个空或空字符串,因为输入字符串中不存在Attribute D

输入这个字符串:

Attribute B: Value 1, Value 2, Value 3 Attribute C: Value 4 Attribute D: Value 5, Value 6, Value 7, Value 8 Attribute E: Value 9, Value 10

我应该得到这个输出:Value 5, Value 6, Value 7, Value 8


我认为这里需要一系列 PHP ifs 和字符串函数,但我想知道是否有人可以记录条件提取代码.. 会加快我的速度:)

自己编写代码:

我首先将字符串分成子字符串,使用: 作为分隔符。然后我遍历每个子字符串并搜索Attribute D 字符串。如果找到,我知道下一个子字符串将具有Attribute D 的值。然后我只删除下一个子字符串中的最后一个单词(即删除下一个 Attribute's 名称)。

虽然此代码中有 2 个缺陷(但不会在我的环境中发生).. 希望你们能找到它们 :)

这是我使用的最终代码:

<?php

    $subStrings = explode(':',$product['description']);

    $arrayIndexContainingAttributeD = -1;

    $length = count($subStrings);
    for ($i = 0; $i < $length; $i++)
    {
      if(strpos($subStrings[$i], 'Attribute D') != false)
      {
        $arrayIndexContainingAttributeD = $i + 1;
        break;
      }
    }

    $attributeDStringAvailable = false;

    if($arrayIndexContainingAttributeD != -1 && $arrayIndexContainingAttributeD<$length)
    {
        $attributeDString = preg_replace('/\W\w+\s*(\W*)$/', '$1', $subStrings[$arrayIndexContainingAttributeD]);
        $attributeDStringAvailable = true;
    }

?>

<?php if ($attributeDStringAvailable == true) { ?>
<h3><a href="<?php echo $product['href']; ?>"><?php echo $attributeDString; ?></a></h3>
<?php } ?>

【问题讨论】:

  • 模式错误.. 我现在会更正。那是为了指出这一点!
  • Attribute 这个词总是存在,还是这个例子?属性可以有空格和其他白色字符吗?关于价值观的同样问题。
  • 如果允许空格,你将如何区分这个字符串Value 3 Attribute B

标签: php string substring


【解决方案1】:

试图使这尽可能不言自明。示例:

$string = 'Attribute B: Value 1, Value 2, Value 3 Attribute C: Value 4 Attribute D: Value 5, Value 6, Value 7, Value 8 Attribute E: Value 9, Value 10';
$query = 'D';
echo getAttributeValues($string, $query);

function getAttributeValues($string = '', $query = null) {
  if(!strpos($string, $query)) {
    echo 'attribute not in string';
  } else {
    $array = explode('Attribute ', $string);
    $attributes = array_filter($array);

    foreach($attributes as $attribute) {
      if(strpos($attribute, $query.':') !== false) {
        $return = str_replace($query.':', '', $attribute);
        return trim($return);
      }
    }
  }
}

http://phpfiddle.org/main/code/9w8-tn0

【讨论】:

  • 但这不会真正起作用,因为在实际示例中,Attribute 名称不一定以“属性”开头......也许我也应该解释一下......我做了更多或更少相同的东西,但使用 : 爆炸
【解决方案2】:

自己编写代码:

我首先将字符串分成子字符串,使用 : 作为分隔符。然后我遍历每个子字符串并搜索属性 D 字符串。如果找到,我知道下一个子字符串将具有属性 D 的值。然后我只需从下一个子字符串中删除最后一个单词(即删除下一个属性的名称)。

虽然此代码中有 2 个缺陷(但不会在我的环境中发生).. 希望你们能找到它们 :)

这是我使用的最终代码:

<?php

    $subStrings = explode(':',$product['description']);

    $arrayIndexContainingAttributeD = -1;

    $length = count($subStrings);
    for ($i = 0; $i < $length; $i++)
    {
      if(strpos($subStrings[$i], 'Attribute D') != false)
      {
        $arrayIndexContainingAttributeD = $i + 1;
        break;
      }
    }

    $attributeDStringAvailable = false;

    if($arrayIndexContainingAttributeD != -1 && $arrayIndexContainingAttributeD<$length)
    {
        $attributeDString = preg_replace('/\W\w+\s*(\W*)$/', '$1', $subStrings[$arrayIndexContainingAttributeD]);
        $attributeDStringAvailable = true;
    }

?>

<?php if ($attributeDStringAvailable == true) { ?>
<h3><a href="<?php echo $product['href']; ?>"><?php echo $attributeDString; ?></a></h3>
<?php } ?>

【讨论】:

    【解决方案3】:

    你可以用一个正则表达式来做到这一点:

    $string = 'Attribute A: Value 1, Value 2 Attribute B: Value 3, Value 4, Value 5, Value 6 Attribute C: Value 7, Attribute D: Value 8, Value 9
    
    Attribute A: Value 1, Value 2, Value 3 Attribute B: Value 4, Value 5 Attribute C: Value 6, Value 7, Value 8, Attribute E: Value 9, Value 10, Value 11
    
    Attribute B: Value 1, Value 2, Value 3 Attribute C: Value 4 Attribute D: Value 5, Value 6, Value 7, Value 8 Attribute E: Value 9, Value 10';
    
    preg_match_all('#Attribute D:\s*(.*?)(?:\s*(?:Attribute|$))#s', $string, $m);
    print_r($m[1]);
    

    输出:

    Array
    (
        [0] => Value 8, Value 9
        [1] => Value 5, Value 6, Value 7, Value 8
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-21
      • 1970-01-01
      • 2014-06-24
      • 1970-01-01
      • 2012-07-02
      • 1970-01-01
      • 2014-05-26
      • 2021-08-03
      相关资源
      最近更新 更多