冲刺后获得数字" - "从一个数组中保留破折号的原始位置。正则表达式

时间:2015-03-03 16:33:58

标签: php html arrays regex numbers

来自其他线程的用户帮助我弄清楚如何从数组中获取数字,但现在我无法获得数字" - "短跑。让我告诉你我拥有什么并让你处于紧张状态。

我有一个包含下一个内容的数组:

Array(
[0] => <tr><td>29/06/2015</td><td>19:35</td><td>12345 Column information</td><td>67899 Column information - 12</td><td>Information</td><td>More information</td></tr>
[1] => <tr><td>12/03/2015</td><td>10:12</td><td>98545 Column information</td><td>67659 Column information - 32</td><td>Information</td><td>More information</td></tr>
[2] => <tr><td>11/02/2015</td><td>12:40</td><td>59675 Column information</td><td>94859 Column information - 11</td><td>Information</td><td>More information</td></tr>
[3] => <tr><td>01/01/2015</td><td>20:12</td><td>69365 Column information</td><td>78464 Column information - 63</td><td>Information</td><td>More information</td></tr>
)

最后我知道如何得到每个数字(除了破折号后的数字&#34; - &#34;):

$re = "/.*?(\\d+)\\s.*?(\\d+)\\s.*/m";
$str = "<tr><td>29/06/2015</td><td>19:35</td><td>12345 Column information</td><td>67899 Column information - 12</td><td>Information</td><td>More information</td></tr>";
$subst = "$1, $2";
$result = preg_replace($re, $subst, $str);

这是$结果;输出:

foreach($result as $finalresult) echo $finalresult.'<br>';

12345,67899
98545,67659
59675,94859
69365,78464

我对所有这一过程的期望并且无法弄清楚是在破折号后获得数字&#34; - &#34;太:

12345,67899-12
98545,67659-32
59675,94859-11
69365,78464-63

但这并没有结束......当破折号后的数字&#34; - &#34;低于50我需要转换$ result输出。请参阅下面的示例。 如果&#34; - &#34;之后的数字&LT;然后它需要进行转换,取第一个数字并将其放在单位位置。然后十位可能为零。 当数字为50或以上时,数字保持不变。例如:

    12345,67899-12 ------> 12345,67899-01
    98545,67659-32 ------> 12345,67899-03
    59675,94859-11 ------> 12345,67899-01
    52375,53259-49 ------> 12345,67899-04
    69365,73464-63 ------> 12345,67899-63
    89765,12332-51 ------> 12345,67899-51
    38545,54213-70 ------> 12345,67899-70

现在是我的头爆炸了!

事先感谢很多的帮助。

3 个答案:

答案 0 :(得分:1)

这可能就是你要找的东西。我略微修改了你的正则表达式。 (.*?<td>){3}将匹配第三个<td>以外的任何内容。子模式?P<first>等中的(?P<first>\d+)称为命名子模式,这使得它们的值易于从$matches数组访问。

$a = [
    '<tr><td>29/06/2015</td><td>19:35</td><td>12345 Column information</td><td>67899 Column information - 12</td><td>Information</td><td>More information</td></tr>',
    '<tr><td>12/03/2015</td><td>10:12</td><td>98545 Column information</td><td>67659 Column information - 32</td><td>Information</td><td>More information</td></tr>',
    '<tr><td>11/02/2015</td><td>12:40</td><td>59675 Column information</td><td>94859 Column information - 11</td><td>Information</td><td>More information</td></tr>',
    '<tr><td>01/01/2015</td><td>20:12</td><td>69365 Column information</td><td>78464 Column information - 63</td><td>Information</td><td>More information</td></tr>',
];

$result = [];

foreach ($a as $row) {
    $p = '#(.*?<td>){3}(?P<first>\d+).*?</td><td>(?P<second>\d+).*?(?P<third>\d+)#';

    if (preg_match($p, $row, $matches)) {
        if ($matches['third'] < 50) {
            $matches['third'] = '0'.$matches['third'][0];
        }
        $result[] =
            $matches['first'] . ',' .
            $matches['second'] . '-' .
            $matches['third'];
    }
}
print_r($result);

输出:

Array
(
    [0] => 12345,67899-01
    [1] => 98545,67659-03
    [2] => 59675,94859-01
    [3] => 69365,78464-63
)

答案 1 :(得分:0)

这将为您解决问题:

$re = '/.*?(\d+)\s.*?(\d+)\s.*?-\s(\d+).*/';
$str = "<tr><td>29/06/2015</td><td>19:35</td><td>12345 Column information</td><td>67899 Column information - 12</td><td>Information</td><td>More information</td></tr>";
preg_match($re, $str, $matches);
if ($matches[3]<50) $matches[3] = floor($matches[3]/10);
$format = '%d,%d-%02d';
$result = sprintf($format, $matches[1], $matches[2], $matches[3]);
echo $result;

请注意,为了便于阅读,我将$re更改为单引号而非双引号,并且我使用preg_match代替preg_replace,因此我可以使用匹配图案。

为了向你解释正则表达式,有一些事情正在发生:

  • /是正则表达式分隔符。
  • .*?.告诉正则表达式匹配任何字符。 *表示要做零次或多次,而?表示要在&#34; lazy&#34;时尚。 .*末尾的普通$re与字符串的其余部分匹配。
  • (\d+)\d是一个通配符,告诉正则表达式匹配任何数字。 +表示&#34;一次或多次&#34;,而()表示要捕获此内容。第一个()包围的群组是$matches[1]
  • \s:是任何空格字符的通配符。
  • -:是文字-字符。

答案 2 :(得分:0)

嗯......我不知道它是否会有所帮助,但是我用RegExr做了这个并且它适合:

(([0-9] +){5})|( - [0-9] {2})

我希望你会发现它有用!