পার্লের কোনও সহজ উপায় যা আমাকে প্রদত্ত ভেরিয়েবলটি সংখ্যাসূচক কিনা তা নির্ধারণ করার অনুমতি দেবে? এর লাইন ধরে কিছু:
if (is_number($x))
{ ... }
আদর্শ হবে। -w
স্যুইচটি ব্যবহার করা হচ্ছে এমন কৌশল যা সতর্কতা ছুঁড়ে না দেয় অবশ্যই পছন্দ করা হয়।
পার্লের কোনও সহজ উপায় যা আমাকে প্রদত্ত ভেরিয়েবলটি সংখ্যাসূচক কিনা তা নির্ধারণ করার অনুমতি দেবে? এর লাইন ধরে কিছু:
if (is_number($x))
{ ... }
আদর্শ হবে। -w
স্যুইচটি ব্যবহার করা হচ্ছে এমন কৌশল যা সতর্কতা ছুঁড়ে না দেয় অবশ্যই পছন্দ করা হয়।
উত্তর:
ব্যবহারের Scalar::Util::looks_like_number()
অভ্যন্তরীণ পার্ল সি এপিআই এর looks_like_number () ফাংশন, যার ফলে সম্ভবত এই কাজ করতে সবচেয়ে কার্যকর উপায় ব্যবহার করে যা। নোট করুন যে স্ট্রিংগুলি "ইনফ" এবং "ইনফিনিটি" সংখ্যা হিসাবে বিবেচিত হয়।
#!/usr/bin/perl
use warnings;
use strict;
use Scalar::Util qw(looks_like_number);
my @exprs = qw(1 5.25 0.001 1.3e8 foo bar 1dd inf infinity);
foreach my $expr (@exprs) {
print "$expr is", looks_like_number($expr) ? '' : ' not', " a number\n";
}
এই আউটপুট দেয়:
1 is a number
5.25 is a number
0.001 is a number
1.3e8 is a number
foo is not a number
bar is not a number
1dd is not a number
inf is a number
infinity is a number
looks_like_number
0x12
হয় না ।
সিপিএএন মডিউলটি দেখুন রেজিএক্সপ :: সাধারণ । আমি মনে করি এটি আপনার যা প্রয়োজন ঠিক তা করে এবং সমস্ত প্রান্তের কেসগুলি পরিচালনা করে (যেমন আসল সংখ্যা, বৈজ্ঞানিক স্বরলিপি ইত্যাদি), যেমন
use Regexp::Common;
if ($var =~ /$RE{num}{real}/) { print q{a number}; }
আসল প্রশ্নটি ছিল কীভাবে বলা যায় যে কোনও ভেরিয়েবল সংখ্যাসূচক ছিল কিনা, যদি এটির "একটি সংখ্যাসূচক মান থাকে" না।
কয়েকটি অপারেটর রয়েছে যার সংখ্যাসূচক এবং স্ট্রিং অপারেন্ডগুলির জন্য অপারেশনের পৃথক পদ্ধতি রয়েছে, যেখানে "সংখ্যাসূচক" অর্থ এমন কোনও কিছু যা মূলত একটি সংখ্যা ছিল বা কখনও সংখ্যার প্রসঙ্গে ব্যবহৃত হত (যেমন $x = "123"; 0+$x
, সংযোজনের আগে, $x
একটি স্ট্রিং, পরে এটি সংখ্যা হিসাবে বিবেচনা করা হয়)।
বলার একটি উপায় হ'ল:
if ( length( do { no warnings "numeric"; $x & "" } ) ) {
print "$x is numeric\n";
}
যদি বিটওয়াইস বৈশিষ্ট্যটি সক্ষম করা থাকে তবে এটি &
কেবল একটি সংখ্যক অপারেটর তৈরি করে এবং একটি পৃথক স্ট্রিং &.
অপারেটর যুক্ত করে, আপনাকে অবশ্যই এটি অক্ষম করতে হবে:
if ( length( do { no if $] >= 5.022, "feature", "bitwise"; no warnings "numeric"; $x & "" } ) ) {
print "$x is numeric\n";
}
(বিটওয়াইজ 5.022 এবং তার বেশি পার্লে উপলব্ধ এবং আপনি use 5.028;
বা তার বেশি হলে ডিফল্টরূপে সক্ষম হয় ))
sub numeric { $obj = shift; no warnings "numeric"; return eval('length($obj & "")'); }
my $obj = shift;
। কেন alভাল?
my $obj = shift
অবশ্যই ব্যবহার করেছি , এটি কেবল আমার কোড থেকে মন্তব্যে সঠিকভাবে স্থানান্তর করিনি, আমি এটি কিছুটা সম্পাদনা করেছি। তবে, sub numeric { my $obj = shift; no warnings "numeric"; return length($obj & ""); }
একই ত্রুটি উত্পাদন করে। অবশ্যই, একটি গোপনীয় বৈশ্বিক পরিবর্তনশীলটি আচরণের ব্যাখ্যা করবে, আমি সে ক্ষেত্রে এটিই প্রত্যাশা করতাম তবে দুর্ভাগ্যক্রমে, এটি এত সহজ নয়। এছাড়াও, যে strict
& দ্বারা ধরা হবে warnings
। আমি ত্রুটি থেকে পরিত্রাণ পাওয়ার জন্য বরং মরিয়া চেষ্টা করেও চেষ্টা করেছি এবং এটি কার্যকর হয়েছে। কোন গভীর যুক্তি নেই, কেবল পরীক্ষা এবং ত্রুটি।
sub numeric { my $obj = shift; no warnings "numeric"; return length($obj & ""); }
print numeric("w") . "\n"; #=>0
, print numeric("x") . "\n"; #=>0
, print numeric("1") . "\n"; #=>0
, print numeric(3) . "\n"; #=>1
, print numeric("w") . "\n"; #=>1
। যদি আপনি দৈর্ঘ্যের চারপাশে একটি ইভাল ('') রাখেন তবে শেষ মুদ্রণটি এটির মতো একটি 0 দেবে। চিত্রে যান.
সাধারণত সংখ্যাটির বৈধতা নিয়মিত প্রকাশের সাথে সম্পন্ন হয়। এই কোডটি নির্ধারণ করবে যে কোনও কিছু সংখ্যাসঙ্গিক রয়েছে এবং সেই সাথে সংজ্ঞায়িত নিক্ষেপ না করার জন্য অপরিজ্ঞাত ভেরিয়েবলগুলি পরীক্ষা করে দেখুন:
sub is_integer {
defined $_[0] && $_[0] =~ /^[+-]?\d+$/;
}
sub is_float {
defined $_[0] && $_[0] =~ /^[+-]?\d+(\.\d+)?$/;
}
এখানে কিছু পড়া বিষয়বস্তু আপনার দিকে নজর দেওয়া উচিত।
\d*\.?\d+
অংশ প্রবর্তন ReDoS ঝুঁকি। আমি এর পরিবর্তে বৈজ্ঞানিক স্বরলিপি ( ব্যাখ্যা এবং উদাহরণ ) অন্তর্ভুক্ত করার পরামর্শ দিচ্ছি /^[+-]?(?!\.(?!\d)|$)\d*(?:\.\d*)?$/
বা করব । সংখ্যার মতো স্ট্রিং এবং সংখ্যার দিক দিয়ে যাওয়া থেকে রোধ করতে এটি দ্বিগুণ নেতিবাচক বর্ণনাহিনী ব্যবহার করে । এটি নীচের সংখ্যাটি নিশ্চিত করতে একটি ইতিবাচক চেহারাটিও ব্যবহার করে। /^[+-]?(?!\.(?!\d)|$)\d*(?:\.\d*)?(?:(?<=[\d.])e[+-]?\d+)?$/i
.
.e0
e
প্রশ্নের একটি সাধারণ (এবং সম্ভবত সরল) উত্তর হ'ল $x
সংখ্যার বিষয়বস্তুটি হ'ল:
if ($x eq $x+0) { .... }
এটি মূল একটি পাঠগত তুলনা করে $x
দিয়ে $x
একটি সাংখ্যিক মান রূপান্তরিত।
$x eq (($x+0)."")
তবে আরও খারাপ সমস্যাটি হ'ল এই ফাংশনটির অধীনে "1.0" সংখ্যাসূচক নয়
নিখুঁত নয়, তবে আপনি একটি রেজেক্স ব্যবহার করতে পারেন:
sub isnumber
{
shift =~ /^-?\d+\.?\d*$/;
}
আমি বিশ্বাস করি না এটি করার জন্য অন্তর্নির্মিত কিছু আছে। আপনি এই বিষয়টিতে যা দেখতে চেয়েছিলেন তার চেয়েও বেশি জন্য, সংখ্যা সনাক্তকরণে পার্লমনক্স দেখুন
কিছুটা আরও শক্তিশালী রেইগেক্স পাওয়া যাবে রেজেএক্সপ :: সাধারণ ক্ষেত্রে ।
দেখে মনে হচ্ছে আপনি পার্ল ভেরিয়েবলের সংখ্যাসূচক কিনা তা জানতে চান। এখানে একটি ফাংশন যা সেই সতর্কবাণীটিকে ফাঁদে ফেলে:
sub is_number{
my $n = shift;
my $ret = 1;
$SIG{"__WARN__"} = sub {$ret = 0};
eval { my $x = $n + 1 };
return $ret
}
আরেকটি বিকল্প হ'ল স্থানীয়ভাবে সতর্কতাটি বন্ধ করে দেওয়া:
{
no warnings "numeric"; # Ignore "isn't numeric" warning
... # Use a variable that might not be numeric
}
নোট করুন যে অ-সংখ্যাসূচক ভেরিয়েবলগুলি নিঃশব্দে 0 তে রূপান্তরিত হবে যা সম্ভবত যাইহোক আপনি চেয়েছিলেন।
যদিও আমি এটি আকর্ষণীয় পেয়েছি
if ( $value + 0 eq $value) {
# A number
push @args, $value;
} else {
# A string
push @args, "'$value'";
}
ব্যক্তিগতভাবে আমি মনে করি যে যাওয়ার উপায় হ'ল সমাধানের বুলেট-প্রুফ তৈরির জন্য পার্লের অভ্যন্তরীণ প্রসঙ্গের উপর নির্ভর করা। একটি ভাল রেজিপ্সে সমস্ত বৈধ সংখ্যাসূচক মান এবং অ-সংখ্যাসূচক কোনটির (বা তদ্বিপরীত) কোনওটির সাথেই মেলে না, তবে দোভাষী যে একই যুক্তি ব্যবহার করছেন সেটিকে সরাসরি ব্যবহার করার জন্য এটি নিরাপদ হওয়া উচিত।
আমি যেমন আমার স্ক্রিপ্টগুলি চালাতে -w
চাইছি, আমাকে "মান প্লাস শূন্য" no warnings
এর ফলাফলকে @ysth ভিত্তিক পদ্ধতির সাথে মূল মানের সাথে তুলনা করার ধারণাটি একত্রিত করতে হবে :
do {
no warnings "numeric";
if ($x + 0 ne $x) { return "not numeric"; } else { return "numeric"; }
}
আপনি $ foo সংখ্যা (বা না) একটি নিয়মিত এক্সপ্রেশন ব্যবহার করতে পারেন।
এখানে একবার দেখুন: স্কেলার একটি সংখ্যা কিনা তা আমি কীভাবে নির্ধারণ করব
যদি (সংজ্ঞায়িত x && & x! ~ এম / \ ডি /) {} বা $ x = 0 হয়! $ x; যদি ($ x! ~ এম / \ ডি /) {
এটি ভীকের উত্তরে কিছুটা ভিন্নতা তবে পরিবর্তনের জন্য আমার যুক্তিটি আমাকে ব্যাখ্যা করতে দিন।
একটি অপরিজ্ঞাত মানতে একটি রেজেক্স সম্পাদন করা ত্রুটির ত্রুটি তৈরি করবে এবং বেশিরভাগ পরিবেশে না থাকলে কোডটি অনেকের মধ্যে প্রস্থান করবে। মানটি সংজ্ঞায়িত করা হয়েছে বা ডিফল্ট কেস সেট করা আছে কিনা তা পরীক্ষা করে দেখছি এক্সপ্রেশন চালানোর আগে বিকল্প উদাহরণে কমপক্ষে আপনার ত্রুটি লগ সংরক্ষণ করবে।
perldoc perlapi
আমাদের বলে: একটি এসভি-এর সামগ্রীটি কোনও সংখ্যার (বা একটি সংখ্যা) মতো দেখায় কিনা তা পরীক্ষা করুন। "ইনফ" এবং "ইনফিনিটি" সংখ্যার হিসাবে বিবেচিত হবে (সুতরাং এটি একটি অ-সংখ্যাসূচক সতর্কতা জারি করবে না), এমনকি যদি আপনার পরিসংখ্যান () এগুলি কঙ্কিত না করে। খুব সহজেই একটি পরীক্ষণযোগ্য স্পেক ...