简体   繁体   English

如何从字符串中的特定文本和字符中获取 integer (Regex/PHP)

[英]How to get integer from specific text and characters in a string (Regex/PHP)

I have been having difficulty extracting specific characters from a string using preg_replace() .我一直难以使用preg_replace()从字符串中提取特定字符。 All the strings are the consistent as displayed below with the two examples.所有字符串都与下面两个示例中显示的一致。

I'm trying to extract the quantity integer, ie.我正在尝试提取数量 integer,即。 for the first example I would get 200 and the second I would get 50 .对于第一个例子,我会得到200 ,第二个我会得到50

Example Strings示例字符串

$string = 'Sunscreen 25g (200 Quantity)';

$string = 'Lubricant 100ml (50 Quantity)';

Regex Code正则表达式代码

$product = preg_replace('/(Sunscreen|Lubricant)/i', '', $string); followed by:其次是:

$product = preg_replace('/(\(d*.Quantity\))/i', '$0', $product)

Expected Result预期结果

From the first string: int(200) Second string: int(50)从第一个字符串: int(200)第二个字符串: int(50)

Any help would be appreciated.任何帮助,将不胜感激。 I cannot get the numbers just before "Quantity" and after the "(".我无法获得“数量”之前和“(”之后的数字。

You don't need to throw multiple preg_ calls at this task, just match the whole string and only capture the digits that follow the first encountered ( . Replace the whole string with the captured digits -- this way there is no temporary array to access; a string input is converted directly into the desired output string.您不需要在此任务中抛出多个preg_调用,只需匹配整个字符串并仅捕获第一个遇到的数字(之后的数字。用捕获的数字替换整个字符串——这样就没有临时数组可以访问; 字符串输入直接转换为所需的 output 字符串。

Code: ( Demo )代码:(演示

$strings = [
    'Sunscreen 25g (200 Quantity)',
    'Lubricant 100ml (50 Quantity)',
    'WD-40 100ml (75 Quantity)',
];

foreach ($strings as $string) {
    echo preg_replace('~[^(]+\((\d+).*~', '$1', $string) . "\n";
}

Output: Output:

200
50
75

In fact, preg_replace() can happily process an array of strings.事实上, preg_replace()可以愉快地处理一个字符串数组。 ( Demo ) 演示

var_export(preg_replace('~[^(]+\((\d+).*~', '$1', $strings));

Breakdown:分解:

[^(]+    #match one or more non-left-parenthesis characters
\(       #match literal left parenthesis
(        #begin capture group 1
  \d+    #match one or more digits
)        #end capture group 1
.*       #match the remainder of the string

Alternatively, if you want to create an array with the quantity digit in it (this is less direct because the target string has to be extracted from the generated array), you can use preg_match() , but there is definitely no reason to use preg_match_all() .或者,如果您想创建一个包含数量数字的数组(这不太直接,因为必须从生成的数组中提取目标字符串),您可以使用preg_match() ,但绝对没有理由使用preg_match_all() \K restarts the full string match so no capture groups are needed. \K重新启动完整的字符串匹配,因此不需要捕获组。

Code: ( Demo )...same output as above代码:(演示)...与上面相同的output

foreach ($strings as $string) {
    echo (preg_match('~\(\K\d+~', $string, $match) ? $match[0] : 'no quantity') . "\n";
}

I found a function in How to get a substring between two strings in PHP?我在How to get a substring between two strings in PHP? 中找到了一个 function? and modified to take only last occrance of '(' and is also found here How to get the last occurrence of a string?并修改为只接受 '(' 的最后一次出现,也可以在这里找到How to get the last occurrence of a string?

 function getValue($string){
      $start = '(';
      $end = 'Quantity';
      $string = ' ' . $string;
      $ini = strrpos($string, $start);
      if ($ini == false) return '';
      $ini += strlen($start);
      $len = strpos($string, $end, $ini) - $ini;
      return substr($string, $ini, $len);
}
        
$product= (int)getValue('Sunscreen 25g (200 Quantity)');
        
var_dump($product);

Instead of doing 2 replacements, you could use a single pattern with a capturing group to get either 200 or 50.您可以使用带有捕获组的单个模式来获得 200 或 50,而不是进行 2 次替换。

Then you can convert group 1 with the digits to an int using for example intval .然后,您可以使用例如intval将带有数字的第 1 组转换为 int。

\b(?:Sunscreen|Lubricant)\h+[^()]*\((\d+)\h+Quantity\)

Explanation解释

  • \b(?:Sunscreen|Lubricant) Word boundary, then match either one of the alternatives \b(?:Sunscreen|Lubricant)字边界,然后匹配其中一个选项
  • \h+ Match 1+ horizontal whitespace chars \h+匹配 1+ 个水平空白字符
  • [^()]*\( Match 0+ times any char except ( and ) [^()]*\(匹配 0+ 次除()之外的任何字符
  • (\d+) Capture group 1 , match 1+ digits (this is the value that you want) (\d+)捕获组 1 ,匹配 1+ 个数字(这是你想要的值)
  • \h+Quantity Match 1+ horizontal whitespace chars \h+Quantity匹配 1+ 个水平空白字符
  • \) Match ) \)匹配)

Regex demo |正则表达式演示| Php demo Php演示

For example例如

$re = '`\b(?:Sunscreen|Lubricant)\h+[^()]*\((\d+)\h+Quantity\)`';
$str = 'Sunscreen 25g (200 Quantity)
Lubricant 100ml (50 Quantity)';

preg_match_all($re, $str, $matches);

$result = array_map("intval", $matches[1]);
var_dump($result);

Output Output

array(2) {
  [0]=>
  int(200)
  [1]=>
  int(50)
}

You might also make the match a bit more specific by matching the digits and the units:您还可以通过匹配数字和单位来使匹配更加具体:

\b(?:Sunscreen|Lubricant)\h+\d+(?:g|ml)\h+\((\d+)\h+Quantity\)

Regex demo正则表达式演示

in your examples, if your strings in back of your numbers is not stable and will change, you can use \d with a plus to extract all numbers from your characters, for example:在您的示例中,如果数字后面的字符串不稳定并且会发生变化,您可以使用 \d 和加号从字符中提取所有数字,例如:

$string = 'Sunscreen 25g (200 Quantity)';
preg_match_all('/\d+/', $string, $match);
print_r($match);

the result should be:结果应该是:

Array
(
    [0] => Array
        (
            [0] => 25
            [1] => 200
        )

)

but if your strings are stable (Sunscreen and Lubricant) you can use this regex:但是如果你的字符串是稳定的(防晒霜和润滑剂)你可以使用这个正则表达式:

$string = 'Sunscreen 25g (200 Quantity)';
preg_match_all('/Sunscreen ([\d\.]*)/i', $string, $match);
print_r($match);

$string = 'Lubricant 100ml (50 Quantity)';
preg_match_all('/Lubricant ([\d\.]*)/i', $string, $match);
print_r($match);

and again result should be:结果应该是:

Array
(
    [0] => Array
        (
            [0] => Sunscreen 25
        )

    [1] => Array
        (
            [0] => 25
        )

)


Array
(
    [0] => Array
        (
            [0] => Lubricant 100
        )

    [1] => Array
        (
            [0] => 100
        )

)

or simpler:或更简单:

$string = 'Sunscreen 25g (200 Quantity)';
preg_match_all('/([\d\.]*) Quantity/i', $string, $match);
print_r($match);

result:结果:

Array
(
    [0] => Array
        (
            [0] => 200 Quantity
        )

    [1] => Array
        (
            [0] => 200
        )

)

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

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