使用正则表达式从字符串中获取匹配模式的最短方法

问题描述:

I have pretty long string to parse, that looks like that (part of it)

$string = 'FIRM_ID = MC0356400000; TAG = EQTV; CURR_CODE = SUR; CLIENT_CODE = FR334; LIMIT_KIND = 1; OPEN_BALANCE = 4822.84; OPEN_LIMIT = 0.00; LEVERAGE = 0;'

I need to get values for php variables from that string, which I do with preg_match:

 preg_match("/FIRM_ID = (.*?);/", $string, $m);
 $firm_id = trim($m[1]);

 preg_match("/CLIENT_CODE = (.*?);/", $string, $m);
 $client_code = trim($m[1]);

... and so on

I was wondering is there a way to do the same in one line? May be with preg_replace or other functions, so I would not have to declare $m variable first and then take out from that [1] element.

So the code supposed to look like

 $firm_id = somefunction($string);
 $client_code = somefunction($string);

Its not practical question, more theoretical. I know how to get result that I need, I want to know if there is a simpler and more elegant way.

Thanks.

我有很长的字符串要解析,看起来像那样(部分) p> \ n

  $ string ='FIRM_ID = MC0356400000;  TAG = EQTV;  CURR_CODE = SUR;  CLIENT_CODE = FR334;  LIMIT_KIND = 1;  OPEN_BALANCE = 4822.84;  OPEN_LIMIT = 0.00;  LEVERAGE = 0;'
  code>  pre> 
 
 

我需要从该字符串中获取php变量的值,我使用preg_match: p>

  preg_match(“/ FIRM_ID =(。*?); /”,$ string,$ m); 
 $ firm_id = trim($ m [1]); 
 
 
preg_match(“/ CLIENT_CODE =  (。*?); /“,$ string,$ m); 
 $ client_code = trim($ m [1]); 
  code>  pre> 
 
 

... 等等 p>

我想知道有没有办法在一行中做同样的事情? 可以使用preg_replace或其他函数,所以我不必先声明$ m变量然后从那个[1]元素中取出。 p>

所以代码应该看起来像 p>

  $ firm_id = somefunction($ string); 
 $ client_code = somefunction($ string); 
  code>  pre> 
 
 

不实际问题,更理论化。 我知道如何得到我需要的结果,我想知道是否有更简单,更优雅的方式。 p>

谢谢。 p> div>

Match and capture key-value pairs and then combine into an array:

$re = '/(\w+)\s*=\s*([^;]*)/';
$str = 'FIRM_ID = MC0356400000; TAG = EQTV; CURR_CODE = SUR; CLIENT_CODE = FR334; LIMIT_KIND = 1; OPEN_BALANCE = 4822.84; OPEN_LIMIT = 0.00; LEVERAGE = 0;';
preg_match_all($re, $str, $matches);
print_r(array_combine($matches[1],$matches[2]));

See the PHP demo, result:

Array
(
    [FIRM_ID] => MC0356400000
    [TAG] => EQTV
    [CURR_CODE] => SUR
    [CLIENT_CODE] => FR334
    [LIMIT_KIND] => 1
    [OPEN_BALANCE] => 4822.84
    [OPEN_LIMIT] => 0.00
    [LEVERAGE] => 0
)

The regex is

/(\w+)\s*=\s*([^;]*)/

See is demo online.

Details:

  • (\w+) - Group 1: one or more word chars
  • \s*=\s* - a = enclosed with optional whitespace(s)
  • ([^;]*) - Group 2: zero or more chars other than ;.

To "initialize" the variables each at a time, you may use a

$var_name = 'FIRM_ID';
$re = '/' . $var_name . '\s*=\s*\K[^;]*/';
$str = 'FIRM_ID = MC0356400000; TAG = EQTV; CURR_CODE = SUR; CLIENT_CODE = FR334; LIMIT_KIND = 1; OPEN_BALANCE = 4822.84; OPEN_LIMIT = 0.00; LEVERAGE = 0;';
preg_match($re, $str, $m);
print_r($m);

See the PHP demo.

The \K is the match reset operator that omits all text matched so far within the current match iteration.

If you remove spaces and replace ; with &, you can do this:

parse_str(str_replace([' ', ';'], ['', '&'], $string), $result);

Which yields an easy to use associative array:

Array
(
    [FIRM_ID] => MC0356400000
    [TAG] => EQTV
    [CURR_CODE] => SUR
    [CLIENT_CODE] => FR334
    [LIMIT_KIND] => 1
    [OPEN_BALANCE] => 4822.84
    [OPEN_LIMIT] => 0.00
    [LEVERAGE] => 0
)

So just echo $result['FIRM_ID'];

You can also use list function after preg_match_all :

preg_match_all('/(\w[\w-]*)\h*=\h*([^;\h]+);/', $string, $matches);

list($firmId, $tag, $currCode, $clientCode, $limitKind, $openBalance, $openLimit, $leverage) = $matches[2];

echo $firmId;
//=> MC0356400000
echo $tag;
//=> EQTV
echo $clientCode;
//=> FR334
echo $openBalance;
//=> 4822.84