简体   繁体   English

php REGEX,尝试从一行中提取两个值(一个可选)

[英]php REGEX, trying to extract two values (one optional) from a line

I have a string with many lines and one of those lines is a temperature reading and the method used to take the temperature like so: 我有一个包含多行的字符串,其中一行是温度读数,而获取温度的方法如下:

Example line 1
temp: 35.20c / 95.36f - axillary
Example line 2

Obviously the temp is "35.20c / 95.36f", and the method is "axillary". 显然温度是“ 35.20c / 95.36f”,方法是“腋下”。 The method part is optional. 方法部分是可选的。 I'm having problems writing a REGEX pattern that will extract both since the method can be optional. 由于该方法可以是可选的,因此我在编写将同时提取两者的REGEX模式时遇到了问题。

So if i run the pattern in a preg_match_all() on the following string: 因此,如果我在以下字符串的preg_match_all()中运行模式:

temp: 35.20c / 95.36f - axillary
temp: 35.20c / 95.36f
temp: 35.20c / 95.36f - oral

I would expect to get a print similar to this: 我希望得到类似的打印:

Array
(
    [0] => Array
        (
            [0] => temp: 35.20c / 95.36f - axillary
            [1] => temp: 35.20c / 95.36f
            [2] => temp: 35.20c / 95.36f - oral
        )

    [1] => Array
        (
            [0] => 35.20c / 95.36f
            [1] => 35.20c / 95.36f
            [2] => 35.20c / 95.36f
        )

    [2] => Array
        (
            [0] => axillary
            [1] => 
            [2] => oral
        )

I have tried many different patterns, so I'll just post my original (which makes sense to me): 我尝试了许多不同的模式,所以我只发布我的原始照片(这对我来说很有意义):

$ptn = "/temp: *(.+)(?: - )?(.+)?/";

Sorry guys I guess I need to add some more details: 抱歉,我想我需要添加更多详细信息:

  • I have no idea what kind of format the temp will be displayed in (35.20c / 95.36f, 35c, 95.3f, etc) 我不知道温度将以哪种格式显示(35.20c / 95.36f,35c,95.3f等)
  • I basically just need to take everything after the "temp: " and before the hyphen as my temp and everything after that is going to be my method. 我基本上只需要将“ temp:”之后和连字符之前的所有内容都当作我的温度,而这之后的所有内容都将成为我的方法。

Try this one: 试试这个:

<?php

    $lines = "temp: 35.20c / 95.36f - axillary
temp: 35.20c / 95.36f
temp: 35.20c / 95.36f - oral";

  preg_match_all("/^temp:\s+([^-\n]+)( - )?(.*)/m", $lines, $matches);

  print_r($matches);

?>

Ah I think your problem is with (.+) matching everything. 嗯,我认为您的问题是(。+)匹配所有内容。 Regex patterns are "greedy" and will try and match as much as they possibly can. 正则表达式模式是“贪婪的”,将尝试并尽可能匹配。 That pattern matches the rest of the string, leaving nothing for the other groups. 该模式与字符串的其余部分匹配,对其他组则什么也没有。

So it looks to me like you want: 所以对我来说,就像您想要的那样:

/^temp: (\d+\.\d+)c \/ (\d+\.\d+)f(?: - ([^$]+))?$/

The centigrade temp will be in $1, the Fahrenheit version will be in $2, and the method will be in $3. 摄氏温度为1美元,华氏温度为2美元,方法为3美元。 ([^$]+) may not be correct dependiing on what you want to do, since it will capture everything up to the end of the line (like whitespace, if there is any). ([^$]+)可能不正确,这取决于您要执行的操作,因为它会捕获到行尾为止的所有内容(如空格,如果有的话)。 You could use (?: - ([^$]+?))?\\s*$/ at the end instead, I think that would fix that. 您可以在最后使用(?: - ([^$]+?))?\\s*$/ ,我认为这样可以解决此问题。

Are the temperatures always in a decimal format? 温度是否始终为十进制格式? Could they ever just be "0c / 32f"? 它们可以是“ 0c / 32f”吗?


Edit: Just saw your update. 编辑:刚刚看到您的更新。 It looks like the greedy .+ is indeed part of the problem, as Rob Agar suggested. 正如罗伯·阿加尔(Rob Agar)所建议的那样,看起来贪婪的.+确实是问题的一部分。 You can try this: 您可以尝试以下方法:

/^temp:\s*(\d+(?:\.\d+)?)c\s*\/\s*(\d+(?:\.\d+)?)f(?:\s*-\s*([^$]+?))?\s*$/

That should work even if the method is more than one word. 即使该方法不只一个单词,也应该可以使用。 Not sure if that's a possibility, I'm making my best guess at your requirements. 不确定是否有这种可能,我正在尽力满足您的要求。

Basically you need a '?' 基本上,您需要一个“?” after the capturing group for the method. 该方法的捕获组之后。 That indicates that the group may not be there, but the pattern as a whole should still match. 这表明该组可能不存在,但是整个模式仍应匹配。 What does your pattern look like at the moment? 目前您的模式是什么样的?

I might be making some assumptions here but you could try the following 我可能在这里做一些假设,但您可以尝试以下方法

/^temp: ((\d+\.\d+c) / (\d+\.\d+f))( - (\w+))?$/

Due to all the sub-groupings, your matching array will contain more items than in your example but the one's you're after should be in there 由于所有子分组,匹配的数组将包含比示例中更多的项目,但是您需要的项应该在其中

$ ptn =“ / temp:(。 )(\\ s- \\ s)?(。 )/”;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM