2017-03-20 6 views
1

データをオンライン会計サイトに渡すモジュールで作業しています。これを正しく解析するために必要なことは、通貨記号を製品。正規表現を使用した通貨記号の問題

$regex = '/^\D?([\d\.,]*)\D?$/is'; 

は私がhttps://regex101.com/ウェブサイト上でこれをテストしてみたし、それが正常に動作しますが、私はpreg_replaceを行う際に、次のように:

$price_no_curr = preg_replace($regex,"$1",$product_price); 

$product_priceを次のように

私の正規表現パターンがあります例えば£123.45の場合、$price_no_currは最初の123.45ポンドと同じです。それで、私はそれを浮動小数点にキャストするとき、何も返しません。

ここで私はこの正規表現に間違っていますか?

答えて

1

最も簡単な解決策、それはUTF-8文字をサポートするために/u修飾子を使用します。

$regex = '/^[^\d\.,]?([\d\.,]*)[^\d\.,]?$/u'; 
$price_no_curr = preg_replace($regex,"$1",$product_price); 
0

£はASCIIの範囲外であり、UTF-8でエンコードされるいくつかのバイトを必要とする:デフォルトで

$a="£"; 
echo implode(' ', array_map(function ($i) { 
    return dechex(ord($i)); 
}, str_split($a))); 
// c2 a3 

正規表現エンジンは、バイト(1バイト=一文字)でバイトを動作します。そのため、\D£の2バイトと一致しません。

マルチバイト文字列で動作させるには、u修飾子をオンにする必要があります。このように正規表現エンジンは、文字列をエンコードするために使用されたバイト数に関係なく、文字列ごとに文字列を読み取ります。 あなたのパターンは次のように書くことができます。

$regex = '/^\D?([\d.,]*)\D?$/u'; 

しかし、あなたはあなたの数量を変更した場合、あなたはまた、U修飾子なしでそれを行うことができます。

$regex = '/^\D*([\d.,]*)\D*$/'; 

よりシンプルかつ柔軟な方法は、すべてのことを取り除くために構成されてい自分の位置を考慮せずに通貨と、最終的にホワイトスペースです:

$str = preg_replace('~[\p{Sc}\s]+~u', '', $str); 

\p{Sc}は、Unicode文字CLASですすべての通貨記号が含まれています。

以上のラジカル:

$str = preg_replace('~[^\d.,]+~u', '', $str); 

または正規表現なし:

$str = '£1823.45'; 
$allowed_chars = [0,1,2,3,4,5,6,7,8,9,'.',',']; 
echo implode('', array_intersect(str_split($str), $allowed_chars));