2012-02-15 75 views
2

字符串考虑以下数组持有的所有美国股票行情,由长下令:检查股票行情在反序列

$tickers = array('AAPL', 'AA', 'BRK.A', 'BRK.B', 'BAE', 'BA'); // etc... 

我想检查一个字符串所有可能的匹配。代号都写有或没有“$”串联到前面:

$string = "Check out $AAPL and BRK.A, BA and BAE.B - all going up!"; 

所有行情都被贴上这样的:{TICKER:XX}。预期结果将是:

Check out {TICKER:AAPL} and {TICKER:BRK.A} and BAE.B - all going up! 

那么行情应该在$行情阵列进行检查,并同时符合,如果他们后面有一个空格或逗号。到现在为止,我一直在使用以下内容:

preg_replace('/\$([a-zA-Z.]+)/', ' {TICKER:$1} ', $string); 

所以我不必检查$ tickers数组。假定所有的收款人都以“$”开头,但这只是约80%的案例中的惯例。因此,需要更新过滤器。

我的问题存在:有一个简单的方法来调整正则表达式来符合新的要求,或者我需要写一个新的功能,因为我是规划先行:

function match_tickers($string) { 
    foreach ($tickers as $ticker) { 
    // preg_replace with $ 
    // preg_replace without $ 
    } 
} 

或者,这可以一气呵成

回答

2

只需使用?(零个或1个匹配项)即可使前导美元符号为可选项。然后,您可以使用相同的技术检查合法的尾随字符。更好的方法是去explode您的输入字符串,并检查/替换每个子字符串与ticker集合,然后重新构建输入字符串。

function match_tickers($string) { 
     $aray = explode(" ", $string); 
     foreach ($aray as $word) { 
      // extract any ticker symbol 
      $symbol = preg_replace('/^\$?([A-Za-z]?\.?[A-Za-z])\W*$/', '$1', $word); 
      if (in_array($symbol,$tickers)) { // symbol, replace it 
       array_push($replacements, preg_replace('/^\$?([A-Za-z]?\.?[A-Za-z])(\W*)$/', '{TICKER:$1}$2', $word)); 
      } 
      else { // not a symbol, just output it normally 
       array_push($replacements, $word); 
      } 
     } 
     return implode(" ", $replacements); 
} 
+0

可能有更有效的方法来使用函数(我的本机“语言”是C#/。NET),但这应该给你一个大致的想法。您进行两次替换的原因是,您首先提取股票代码,然后将其替换为潜在的尾随字符。我不认为你可以一步做到这一点,因为股票代码不会包含你需要的标点符号。 – tvanfosson 2012-02-15 13:57:00

1

我觉得只是你的正则表达式的微小变化应该做的伎俩: “?”

\$?([a-zA-Z.]+) 

我加入在“$”,这意味着它可以出现0次或1次

+0

这并不检查匹配的元素是否在已知代号的集合中,也就是说,它也会匹配'Check','和''all',...它也没有考虑到模式现在匹配子字符串(因为前导$是可选的)。 – tvanfosson 2012-02-15 13:38:34

+0

够真实。就像其中一个答案中已经提到的那样,这应该与循环 – Darvex 2012-02-15 13:42:20

0

$符号后添加?也将接受的话,即,“出”

的preg_replace接受阵列的图案,因此,如果前这是根据http://php.net/manual/en/function.preg-replace.php

preg_replace($tickers, ' {TICKER:$1} ', $string);

:你改变$行情数组: $tickers = array('/AAPL/', '/AA/', '/BRK.A/', '/BRK.B/', '/BAE/', '/BA/');

那么这应该做的伎俩

+0

一起使用'没有人想要买一个{TICKER:aa} rdvark作为宠物。' – tvanfosson 2012-02-15 13:40:51

1

您可以在数组上使用一个foreach循环来替换字符串中的股票行情。

$tickers = array('AAPL', 'AA', 'BRK.A', 'BRK.B', 'BAE', 'BA'); 
$string = 'Check out $AAPL and BRK.A, BA and BAE.B - all going up!'; 

foreach ($tickers as $ticker) { 
    $string = preg_replace('/(\$?)\b('.$ticker.')\b(?!\.[A-Z])/', '{TICKER:$2}', $string); 
} 

echo $string; 

将输出

退房{股票代码:AAPL}和{股票代码:BRK.A},{股票代码:BA}和BAE.B - 都去了!

+0

这会工作,但效率很低。这是一个O(N * M),其中N是字符串中单词的数量,M是自动收报器符号的数量。一个更好的算法将利用代码中的O(1)数组查找并且具有复杂度O(N)。 – tvanfosson 2012-02-15 13:45:45