2009-07-11 29 views
9

Tôi đang sử dụng Perl để chuyển đổi một số XML thành JSON. Nếu thuộc tính XML là một số, tôi không muốn đặt dấu ngoặc kép xung quanh nó để JSON sẽ coi nó là một số và không phải là một chuỗi. Làm thế nào tôi có thể biết nếu một chuỗi Perl là một số (chỉ chứa các số từ 0 đến 9 và có thể là một dấu thập phân)?Trong Perl, làm cách nào tôi có thể biết chuỗi là một số?

Trả lời

19

Các JSON specification cung cấp quy định khá rõ ràng về định dạng của một số, vì vậy regex sau nên làm việc:

/^-?(0|([1-9][0-9]*))(\.[0-9]+)?([eE][-+]?[0-9]+)?$/ 
20

Hãy thử Scalar::Util::looks_like_number:

Ví dụ:

use Scalar::Util qw(looks_like_number); 

if (looks_like_number($thingy)) { 
    print "looks like $thingy is a number...\n" 
} 
+7

chỉ nhận ra rằng look_like_number trả về giá trị đúng cho 'inf', 'nan', '1E02' và có thể là một vài chuỗi khác mà bạn có thể không mong đợi là số. – mirod

+2

tại sao '1E02' không được mong đợi là một số?đó là ký hiệu khoa học cho 100. –

2

Tôi nghĩ this câu hỏi từ perlfaq giải quyết vấn đề của bạn.

Thường thì vấn đề là xác định chính xác bạn muốn đọc số nào.

  • là số "-1.312" hợp lệ?
  • là "inf"?
  • 5.34123412E-03?
4

Bạn chỉ có thể ép nó thành một số sau đó so sánh với chuỗi ban đầu.

if($value eq $value+0){ 
    print "$value is a number\n"; 
} 

(Lưu ý: nó sẽ chỉ làm việc cho số đơn giản, giống như 123 hoặc 12,3)

+0

Có phải "0" giống với "0e0" hoặc "0.0" hoặc "-0" không? Perl thường nghĩ như vậy, nhưng thử nghiệm của bạn tạo ra kết quả ngược lại. – jrockway

-1

Nó có thể được dễ dàng hơn để bạn có thể chỉ cần đọc XML thành một cấu trúc dữ liệu trong Perl và để JSON Perl thư viện hình nó ra cho bạn. Nó đã kiểm tra điều đó, do đó, trừ khi số của bạn thực sự là một chuỗi trong XML (ví dụ: nó có một dấu cách sau nó, vv) JSON->encode() sẽ mã hóa nó dưới dạng một số JSON.

3

Tôi nghĩ (từ những trải nghiệm gần đây) rằng bạn đang phạm sai lầm khi thực hiện bất kỳ loại chuyển đổi XML -> thủ công nào. Tôi gặp phải nhiều gotchas trong quá trình này, không ít nhất trong số đó liên quan đến các ký tự thoát không chính xác.

Tôi khuyên bạn nên phân tích cú pháp XML của bạn bằng một trong nhiều mô-đun XML :: * (tôi đã sử dụng XML :: Đơn giản) và sau đó hiển thị nó dưới dạng JSON sử dụng JSON :: XS. JSON :: XS cho phép bạn chuyển đổi cấu trúc dữ liệu Perl thành JSON; XML :: Đơn giản phân tích XML thành cấu trúc dữ liệu Perl. Trong thời gian có nghĩa là bạn có thể thao tác cấu trúc dữ liệu Perl như bạn muốn.

Điểm mấu chốt là bạn không còn quan tâm đến các ký tự trích dẫn/thoát.

3

Giả sử bạn không cần phải hỗ trợ những thứ khác thường (như khoa học viễn tưởng ký hiệu) này hầu như làm việc (và rất đơn giản):

#!/usr/bin/perl 

my $foo = '1234.5'; 

if($foo =~ /\d+/){ 
    print "$foo is a number\n"; 
} 

Lý do nó không hoàn toàn làm việc là vì bạn có thể có dấu gạch nối và dấu chấm ở bất kỳ đâu (bao nhiêu tùy thích) miễn là bạn có ít nhất một chữ số hiện tại). '--1--2' đánh giá bằng không, và '1.2.3.4.5' evals là 1.2 (dấu chấm thứ hai và mọi thứ sau được bỏ qua). Điều này có thể hoặc không có thể là một vấn đề cho bạn.

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