2014-06-24 2 views
1

У меня есть строка, которая может читать что-то вроде этого (хотя не всегда, цифры могут меняться).Почему это регулярное выражение не соответствует Perl?

Board Length,45,inches,color,board height,8,inches,black,store,wal-mart,Board weight,20,dollars 

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

if ($string =~/Board Length,(\d+\.\d+)/){ 

    print $string; 

} 

Является ли форматирование неправильным? Я думал, что d + будет соответствовать столько чисел, сколько необходимо. будет соответствовать буквальному '.', а d + будет соответствовать любым числам после десятичной (если они есть).

ответ

2

Как вы выразились, десятичные цифры . и следующие цифры являются обязательными. Таким образом (\.\d+)? сделать необязательным,

if ($string =~/Board Length,(\d+(?:\.\d+)?)/) 
2

Вы абсолютно правы о том, что должно совпадать. Однако без «?» характер, вы указываете, что все эти части должны присутствовать.

\d+\.\d+ 

Это означает, что "1 или более цифр, период, 1 или несколько номеров"

1.5, 253333,7, 0,0 бы все совпавшие. Однако в вашем примере используется 45, у которых нет «.». в нем, а не числа потом. Есть несколько решений вашей проблемы, наиболее полное доказательство которых было указано выше mpapac. Разрешить десятичную и следующие цифры необязательно.

(\.\d+)? 

Проблема с этим как таковым заключается в том, что помещение() вокруг него делает его другой группой захвата. Вы можете или не хотите этого. Ввод?: Внутри означает «Использовать это как группу, но не захватывать». Следовательно:

(?:\.\d+)? 

Другой вариант не делать группировку, и вместо того, чтобы сделать как десятичное сам опциональные и цифры после десятичной ZERO или более вместо одного или более. Это будет выглядеть примерно так:

\d+\.?\d* 
1

Вы не печатаете то, что вы снимаете. Вы печатаете $_, который мы не знаем, что это такое.

if ($string =~/Board Length,(\d+\.\d+)/){ 
    print $_; 
} 

То, что я думаю, что вы хотите:

if ($string =~/Board Length,(\d+\.\d+)/){ 
    print $1; 
} 
+0

Да, я в конечном итоге поймать, что немного после того, как я отправил это. Благодарю. – user1768884

0

Вы следующее выражение:

$string =~/Board Length,(\d+\.\d+)/

ваша строка это:

Board Length,45,inches 

Строка будет соответствовать шаблону Board Length,. Однако остальная часть нашего шаблона соответствует одной или нескольким цифрам с последующим периодом, следующим за одной или несколькими цифрами. Это не соответствует строке 45. Там нет десятичной дроби.

Вопрос в том, что вы пытаетесь найти.Например, если число окружено запятыми, вы можете сделать это:

$string =~ /Board Length,([^,]+),/; 
my $number = $1; 

[^,] означает Не запятая. Вы записываете все после запятой в следующую запятую. Это позволит вам захватить 45, 45.32 и даже 4.5e+10. Просто что-нибудь между этими двумя запятыми.

Обратите внимание, что вы используете $1 для своей первой группы захвата, а не $_.

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

$string =~ /Board Length,(.+?),/; 
my $number = $1; 

Что произойдет, если то, что захватывается не является числом? Вы можете проверить, что с помощью looks_like_number функции из Scalar::Util (который был включен в дистрибутивах Perl в течение длительного времени) .:

use Scalar::Util qw(looks_like_number); 

my $string = "Board Length,Extra long,feet,..."; 
... 
$string =~ /Board Length,(.+?),/; 
my $number = $1; 

if (looks_like_number($number)) { 
    print "$number is a number\n"; 
} 
else { 
    print "Nope. $number isn't a number\n"; 
} 
Смежные вопросы