2013-12-12 3 views
0

Как найти все числа, содержащиеся в строке, кроме тех, которые содержат в них букву (например, A1)? Например, в строку «saddfs 2300 dfsfd 45 A3 A6» Я только хочу, чтобы получить 2300 и 45.PHP Number Substring

Я знаю, что

preg_match_all('!\d+!', $string, $nums); 

можно найти все номера, но я не хочу, чтобы найти номера от A3, A6 тоже.

Спасибо!

ответ

2

Просто используйте слово краевым или строковые границы:

preg_match_all('!(^|\b)\d+(\b|$)!', $string, $nums); 

Некоторые тесты:

php > preg_match_all('!(^|\b)\d+(\b|$)!', 'saddfs 2300 dfsfd 45 A3 A6', $nums); 
php > print_r($nums[0]); 
Array 
(
    [0] => 2300 
    [1] => 45 
) 
php > preg_match_all('!(^|\b)\d+(\b|$)!', 'saddfs 2300 dfsfd 45 A3 A6 123', $nums); 
php > print_r($nums[0]); 
Array 
(
    [0] => 2300 
    [1] => 45 
    [2] => 123 
) 
php > preg_match_all('!(^|\b)[0-9]+(\b|$)!', '789 saddfs 2300 dfsfd 45 A3 A6 123', $nums); 
php > print_r($nums[0]); 
Array 
(
    [0] => 789 
    [1] => 2300 
    [2] => 45 
    [3] => 123 
) 

UPDATE: измененные \d в [0-9] за предложение Zsolt Szilagy в.

+0

Кстати, вы можете заменить \ d на [0-9]. \ d также находит китайские, тайские и японские цифры (всего более 1000 символов), и они могут обходить проверки безопасности и удалять базу данных при работе с дефоктически закодированными данными. –

+0

@ZsoltSzilagy Хорошая точка. Обновление ответа ... –

2

Non-надежный, быстрый и грязный - и неправильно - решение:

$ php -a 
Interactive shell 

php > preg_match_all('/\W\d+\W/', 'saddfs 2300 dfsfd 45 A3 A6', $matches); 
php > print_r($matches); 
Array 
(
    [0] => Array 
     (
      [0] => 2300 
      [1] => 45 
     ) 

) 

Update Per Aleks G предложение, выложив подводные камни к этому решению:

Первая проблема : это не соответствует чистым числам при строгом начале или конце строки. Чтобы сделать это, выполните Aleks G шаблон, который ставит якорные символы в захвате суб-моделей:

preg_match_all('/(^|\W)\d+(\W|$)/', '2300 df A6 242 sfd 45', $matches); 

Вы можете сделать шаблон без захвата ('/(?:^|\W)\d+(?:\W|$)/'), чтобы сигнализировать свое намерение, что круглые скобки для группировки, а не для захват - но это чисто необязательно, поскольку значения, которые вы все еще хотите, остаются в $matches[0].

Вторая проблема: \ b и \ W не совсем то же самое. \ b является «границей слов», а \ W «не является символом слова». Сравните результат Aleks G и мой ответ, и вы увидите, что \ b возвращает чистые числа, а \ W возвращает окружающее пространство.

Обновление За комментарий Zzolt Szilagy, \ d соответствует цифрам в текущем наборе символов, поэтому для языков с более цифровыми символами (например, китайский) вы не получите ожидаемых от 0 до 9. Для этого используйте класс символов [0-9].

+0

Это не будет работать для чисел в начале или конце строки. Проверьте свой код со строкой ''saddfs 2300 dfsfd 45 A3 A6 123'' - последний' 123' не будет сопоставлен. –

+0

@AleksG: Я знаю об этом. Что-то нужно оставить читателю для определения. – bishop

+0

Если вы знаете об этом и целенаправленно оставьте его в ОП, чтобы определить, вы должны явно указать это в своем ответе. В противном случае это встречается как небрежность или лень. –