2015-10-13 2 views
0

Я пытаюсь написать регулярное выражение для проверки, если строка соответствует не пустому шаблону CSV с положительными целыми числами, например 34,657547,453,346654, но и отдельными целыми числами, как 2 или 3943.Regex для непустого CSV строки положительных целых чисел

Я попытался ^\d+(,\d+)*$ как регулярное выражение (как описан в this SO-question и удалении части, которая позволяет пустую строку), но если я попробовать это на https://regex101.com/ с моим примером вводом 34,657547,453,346654 он говорит мне, что единственный матч будет ,346654. Если я пытаюсь 34 он говорит, не спички

для моего понимания:

^ // Start of String 
\d+ // A digit, at least one time 
(...) // Grouping for the next 
,\d+ // a comma and at least one digit 
* // Repeating the grouping zero to unlimited times 
$ // End of String 

Так мои тоже вопросы:

  1. Так что я должен изменить, что я получаю то, что мне нужно?
  2. Есть ли способ не допускать, чтобы ноль также являлся одной записью? Таким образом, 34,0,354 или 0 недействительны. Я думал об использовании [1-9] вместо \d в моем регулярном выражении, но это бы вычеркнуло цифры 10, 1034.

В конце концов, я имею в виду сценарий, включая функции, как это:

function validateCSV($string) { 
    $regEx = "^\d+(,\d+)*$"; 

    // Don't know if this preg_match syntax is right. 
    // Didn't wrote the script yet because of the failure (?) of my regex in onlinetool 
    return (preg_match($regEx, $string) > 1) ? true : false; 
} 
+3

Вы неправильно интерпретируете вывод regex101. Он соответствует всей строке, но ** фиксирует ** только последнее число - последний номер, сопоставляемый символом '(, \ d +)'. Он помещается внутри '()' для повторения, но это также означает, что это группа захвата. Вы можете сделать это группой без захвата, запустив ее с помощью:? - '^ \ d + (?:, \ D +) * $', но в вашем случае это не обязательно. Вы хороши, как есть. – ClasG

+0

@ClasG Я принял ответ Марианоса, но я хотел бы поблагодарить вас за объяснение группы (не) захвата! Поэтому я проголосовал хотя бы за ваш комментарий;) – bish

ответ

1

Как ClasG отметил в комментарии, ваше регулярное выражение работает. Это действительно соответствует всей строке, и только захват маркера las соответствует. Группа (,\d+)* перезаписывается при повторении.

Для того, чтобы исключить соответствующие 0 маркеры, вы можете использовать следующее выражение:

/^0*[1-9]\d*(?:,0*[1-9]\d*)*$/ 

regex101 demo


Как вы можете видеть, для каждого номера, это соответствует:

0*   # any number of leading zeros 
[1-9]  # requires 1 digit different than 0 
\d*   # any number of digits 

Еще одна вещь, вы проверяете, preg_match($regEx, $string) > 1. Однако preg_match возвращает 1, если соответствует, или 0 иначе в этом случае (мы не используем смещение). Вы можете с полной уверенностью вернуть значение:

return preg_match($regEx, $string); 
+0

Итак, если я изменил ваше регулярное выражение на '^ [1-9] \ d * (?:, [1-9] \ d *) * $', чем ведущие нули (например, '034 ') также недопустимы? Или я снова не могу интерпретировать regex101? – bish

+0

Это точно. – Mariano

Смежные вопросы