2017-10-17 46 views
1

我试图回显每个数组键的度量单位的名称。如何使用strpos匹配大部分单词?

问题在于,有时候存在具有缩写的关键值,正如我在干草堆变量中的最后一个关键值中所显示的那样。

$haystack = array(
    '15.1 ounces white chocolate', 
    '1 ounce olive oil', 
    '½ cup whipping cream', 
    '1 tablespoon shredded coconut', 
    '1 tablespoon lemon', 
    '1 oz water' 
); 

$needles = 
    array(
     '0' => array(
      'id' => '1', 
      'name' => 'cup', 
      'abbreviation' => 'c' 
     ), 
     '1' => array(
      'id' => '2', 
      'name' => 'ounce', 
      'abbreviation' => 'oz' 
     ), 
     '2' => array(
      'id' => '3', 
      'name' => 'teaspoon', 
      'abbreviation' => 'tsp' 
     ), 
     '3' => array(
      'id' => '4', 
      'name' => 'tablespoon', 
      'abbreviation' => 'tbsp' 
    ) 
); 

foreach($haystack as $hay){ 
    foreach($needles as $needle){ 
     if(strpos($hay, $needle['name']) !== false || strpos($hay, $needle['abbreviation']) !== false){ 
      $names[] = $needle['id']; 
     } 
    } 
} 

上面的代码返回的结果如下(http://codepad.org/yC47JLeC):

Array 
(
    [0] => cup 
    [1] => ounce 
    [2] => cup 
    [3] => ounce 
    [4] => cup 
    [5] => cup 
    [6] => tablespoon 
    [7] => tablespoon 
    [8] => ounce 
) 

我试图做到的是,使之返回的结果如下(http://codepad.org/MZXNOGnr):

Array 
(
    [0] => 2 
    [1] => 2 
    [2] => 1 
    [3] => 4 
    [4] => 4 
    [5] => 2 
) 

但是为了让它在“工作”代码中返回结果,我必须在缩写字符前加上1,这样strpos就不会与那些不正确的字符匹配。

回答

2

'cup'的缩写'c'太多了。你需要检查它是否是一个整词。你可以通过在空格中嵌入搜索字符串来实现,因此请查找" c "而不是"c",或者使用正则表达式和字边界上的匹配。

请注意,如果您改变了这一点,您将不得不在针上添加“盎司”,“杯子”和“汤匙”(复数形式),否则您将无法找到它们。事实上,而不是写一个缩写,我会继续为各单位“变化”的数组,所以你会得到这样的:

$needles = 
    array(
     '0' => array(
      'id' => '1', 
      'name' => 'cup', 
      'variations' => array('cups', 'cup', 'cp', 'c') 
     ), 
    ... 

然后,您可以搜索每个针的每个变化。

+1

我同意这将是最好的方法,此刻你的'c'太模糊了比赛。 (因此你为什么要买巧克力,奶油和椰子配料)。 –

+0

我将每个单元的序列化变体存储到数据库中,就像您的示例一样,它比在字符串之间嵌入空白效率更高效。谢谢。 – Craig