регулярные выражения для замены шаблона денег - PullRequest
1 голос
/ 16 июля 2009

Я хотел бы попросить помощи с этим, я хотел проверить строку сопоставление десятичной дроби с последующей буквой (15M, 15,3M, 15T или 15,3T) и замените его нулями.

Как это: 15M -> 15000000 15,3M -> 15300000 15T -> 15000 15,3T -> 15300

Я пытался сделать это с str_replace, но не могу сделать это правильно. надежда кто-то может мне помочь.

Ответы [ 4 ]

3 голосов
/ 16 июля 2009

«Т» может быть «тысяча» или «триллион», вы знаете.

$s = "15.7T";

$factors = Array('T' => 1000, 'M' => 1000000, 'B' => 1000000000.);

$matches = Array();
if (0 < preg_match('/([0-9]+(?:\.[0-9]*)?)([TMB])/', $s, $matches)) {
    print("$s -> " . $matches[1] * $factors[$matches[2]]);
}

печать:

15.7T -> 15700

редактирование:

Закрепление (любой мусор спереди или сзади означает отсутствие совпадения):

'/^(...)$/'

Вы можете разрешить использование пробелов, однако:

'/^\s*(...)\s*$/'

Вы также можете использовать "\ d" вместо "[0-9]:

'/(\d+(?:\.\d*)?)([TMB])/'

Нечувствительность к регистру:

'/.../i'
...
print("$s -> " . $matches[1] * $factors[strtoupper($matches[2])]);

Необязательный коэффициент:

'/([0-9]+(?:\.[0-9]*)?)([TMB])?/'
$value = $matches[1];
$factor = isset($matches[2]) ? $factors[$matches[2]] : 1;
$output = $value * $factor;

Используйте printf для управления форматированием вывода:

print($value) -> 1.57E+10
printf("%f", $value);  -> 15700000000.000000
printf("%.0f", $value);  -> 15700000000

Stephan202 рекомендуется хитрый трюк, поставьте "?" (необязательно) в скобках, и вы гарантированно соответствуете строке, она может быть просто пустой. Затем вы можете использовать пробел в качестве ключа массива, чтобы получить значение по умолчанию, не проверяя, соответствует ли оно или нет.

Собираем все это вместе:

$factors = Array('' => 1, 'T' => 1e3, 'M' => 1e6, 'B' => 1e9);
if (0 < preg_match('/^\s*(\d+(?:\.\d*)?)([TMB]?)\s*$/i', $s, $matches)) {
    $value = $matches[1];
    $factor = $factors[$matches[2]];
    printf("'%s' -> %.0f", $s, $value * $factor);
}
2 голосов
/ 16 июля 2009

Альтернативная версия, которая выполняет преобразование по всем найденным ценам:

  $multiply = array('' => 1, 'T' => 1000, 'M' => 1000000);

  function convert($matches) {
    global $multiply;
    return $matches[1] * $multiply[$matches[3]];
  }

  $text = '15M 15.3M 15.3T 15';
  print(preg_replace_callback('/(\d+(\.\d+)?)(\w?)/', 'convert', $text));
0 голосов
/ 16 июля 2009

Понятия не имею, как сделать это одним регулярным выражением, вот моя попытка в Ruby.

#!/usr/bin/ruby

def trans s
h={"M"=>10**6 ,"T"=>10**3}
a = s.split(/[MT]/) + [s.split("").last]
(a[0].to_f * h[a[1]]).to_i
end


puts trans "15M"
puts trans "15.3M"
puts trans "15T"
puts trans "15.3T"
0 голосов
/ 16 июля 2009

В Perl:

#!/usr/bin/perl

use strict;
use warnings;

my %factors = (
    B => 1_000_000_000,
    M => 1_000_000,
    T => 1_000,
);

while ( <DATA> ) {
    next unless m{
        ^
        (?<number> -? [0-9]+ (?:\.[0-9]+)? )
        (?<factor>B|M|T)?
        $
    }x;
    my $number = $+{factor}
               ? sprintf( '%.0f', $+{number} * $factors{ $+{factor} } )
               : $+{number}
               ;
    print $number, "\n";
}

__DATA__
15M
15B
15T
15.3M
15.3B
15.3T
15
15.3

Выход:

C:\Temp> z
15000000
15000000000
15000
15300000
15300000000
15300
15
15.3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...