2010-08-26 76 views
8

Tôi cóLàm thế nào để trích xuất một số từ một chuỗi trong Perl?

print $str; 
abcd*%1234$sdfsd..#d 

Chuỗi sẽ luôn luôn chỉ có một dải liên tục của các con số, như 1234 trong trường hợp này. Phần còn lại tất cả sẽ là bảng chữ cái hoặc các ký tự đặc biệt khác.

Làm cách nào tôi có thể trích xuất số (1234 trong trường hợp này) và lưu trữ lại trong str?

This page khuyên tôi nên sử dụng \d, nhưng làm cách nào?

Trả lời

17
$str =~ s/\D//g; 

Điều này sẽ xóa tất cả các ký tự không có số ký tự khỏi chuỗi. Đó là tất cả những gì bạn cần làm.

EDIT: nếu Unicode chữ số trong các kịch bản khác có thể có mặt, một giải pháp tốt hơn là:

$str =~ s/[^0-9]//g; 
+1

Lazer yêu cầu một số, không chỉ là số nguyên. Regexp này sẽ thả '.',' e' có thể được sử dụng để tạo thành một phao. Ngoài ra '\ d' không chỉ là' [0-9] ', do hỗ trợ Unicode trong Perl: các chữ số trong các chữ cái khác (như ấn độ) là hợp lệ. Vì vậy, regexp của bạn cũng sẽ chấp nhận các chuỗi không phải là số. – dolmen

+0

@dolmen Lazer nên cụ thể hơn, sau đó. Ví dụ của ông không bao gồm số thập phân hoặc số mũ, và tôi không thể biết chắc chắn liệu ông có muốn đưa họ vào hay không. Mặc dù vậy, bạn đã sửa về các chữ số của tập lệnh biến thể unicode, tôi sẽ chỉnh sửa. –

26

Nếu bạn không muốn thay đổi chuỗi ban đầu, bạn có thể trích xuất các con số bằng cách bắt chúng trong regex, sử dụng subpatterns. Trong ngữ cảnh danh sách, một biểu thức chính quy trả về các kết quả phù hợp được xác định trong các mẫu con.

my $str = 'abc 123 x456xy 789foo'; 

my ($first_num) = $str =~ /(\d+)/; # 123 
my @all_nums = $str =~ /(\d+)/g; # (123, 456, 789) 
+0

+1. Điều này có lợi thế hơn câu trả lời của tôi rằng nó không giả định chỉ có một số nhúng trong chuỗi. –

1

Cá nhân, tôi sẽ làm điều đó như thế này:

$s =~ /([0-9]+)/; 
print $1; 

$ 1 sẽ chứa nhóm đầu tiên xuất hiện các biểu thức chính quy định (phần trong ngoặc tròn).

+2

Không bao giờ sử dụng giá trị trong '$ 1',' $ 2', v.v. trừ khi bạn đã xác nhận lần đầu rằng kết quả khớp của bạn thành công. Biến chụp chỉ được đặt lại thành một trận đấu thành công, nếu '$ s' trong ví dụ của bạn không có bất kỳ chữ số nào, bạn sẽ nhận được kết quả của trận đấu cuối cùng của bạn. –

+0

Chà, thật ngớ ngẩn của tôi. Cảm ơn lời giải thích. Chỉ cần để đảm bảo rằng tôi học bài học của tôi ... Là 'if ($ s = ~/([0-9] +) /) in $ 1' một cách chính xác để sử dụng các biến nhóm? – Ziggy

4

Nếu bạn muốn làm điều đó theo cách phá hoại, đây là cách nhanh nhất để làm điều đó.

$str =~ tr/0-9//cd; 

tr anslate tất cả các nhân vật trong c omplement của 0-9 không có gì, d elete họ.

Thông báo trước cho phương pháp này, và Phillip Potter, là có một nhóm chữ số khác tiếp tục xuống chuỗi, chúng sẽ được nối với nhóm chữ số đầu tiên. Vì vậy, nó không rõ ràng rằng bạn sẽ muốn làm điều này.

Cách chắc chắn để có được một và chỉ một nhóm các chữ số là

($str) = $str =~ /(\d+)/; 

Trận đấu, trong một bối cảnh danh sách trả về một danh sách các ảnh chụp. Các parens xung quanh $str chỉ đơn giản là đặt biểu thức trong ngữ cảnh danh sách và gán ảnh chụp đầu tiên cho $str.

+0

Câu trả lời hay nhất! – dolmen

Các vấn đề liên quan