আমার কাছে বিভিন্ন স্ট্রিং রয়েছে, কিছু "45" এর মতো, কিছু "45px" এর মতো। আমি কীভাবে এই দুটিকেই 45 নম্বরে রূপান্তর করব?
"9"
পরিণত 9
, এই ভাল জিনিস যে আমার জন্য কাজ হল: (Integer. "9")
।
আমার কাছে বিভিন্ন স্ট্রিং রয়েছে, কিছু "45" এর মতো, কিছু "45px" এর মতো। আমি কীভাবে এই দুটিকেই 45 নম্বরে রূপান্তর করব?
"9"
পরিণত 9
, এই ভাল জিনিস যে আমার জন্য কাজ হল: (Integer. "9")
।
উত্তর:
এটি কাজ করবে 10px
বাpx10
(defn parse-int [s]
(Integer. (re-find #"\d+" s )))
এটি কেবলমাত্র প্রথম ধারাবাহিক অঙ্ককে পার্স করবে
user=> (parse-int "10not123")
10
user=> (parse-int "abc10def11")
10
Exception in thread "main" java.lang.ClassNotFoundException: Integer.,
আমি স্ন্রোবোটের উত্তরটি আরও ভাল পছন্দ করি। এই সাধারণ ব্যবহারের ক্ষেত্রে রিড-স্ট্রিং ব্যবহার করার চেয়ে জাভা পদ্ধতিটি ব্যবহার করা সহজ এবং আরও শক্ত। আমি কয়েকটি ছোট পরিবর্তন করেছি। যেহেতু লেখক নেতিবাচক সংখ্যাগুলি বাতিল করে দেয় না, তাই আমি নেতিবাচক সংখ্যার অনুমতি দেওয়ার জন্য এটিকে সামঞ্জস্য করেছি। আমি এটিও তৈরি করেছি যাতে স্ট্রিংয়ের শুরুতে এটির সংখ্যাটি শুরু হয়।
(defn parse-int [s]
(Integer/parseInt (re-find #"\A-?\d+" s)))
শীর্ষস্থানীয় শূন্যগুলি থাকা সত্ত্বেও, যখন কোনও রেডিক্স দেওয়া হয় না তখন পূর্ণসংখ্যা / পার্সইন্ট দশমিক হিসাবে পার্স করে।
প্রথমত, কেবলমাত্র একটি পূর্ণসংখ্যা পার্স করা (যেহেতু এটি গুগলে হিট এবং এটি ব্যাকগ্রাউন্ডের ভাল তথ্য):
আপনি পাঠক ব্যবহার করতে পারেন :
(read-string "9") ; => 9
এটি পরীক্ষা করার পরে আপনি এটি পরীক্ষা করতে পারেন:
(defn str->int [str] (if (number? (read-string str))))
আমি নিশ্চিত নই যে ব্যবহারকারীর ইনপুটটি ক্লোজার রিডার দ্বারা বিশ্বাস করা যায় কিনা তাই এটি পড়ার আগে আপনি পরীক্ষা করতে পারেন:
(defn str->int [str] (if (re-matches (re-pattern "\\d+") str) (read-string str)))
আমি মনে করি আমি শেষ সমাধানটি পছন্দ করি।
এবং এখন, আপনার নির্দিষ্ট প্রশ্ন। কোনও পূর্ণসংখ্যার সাথে শুরু হওয়া কোনও জিনিসকে পার্স করতে যেমন 29px
:
(read-string (second (re-matches (re-pattern "(\\d+).*") "29px"))) ; => 29
if
হওয়া উচিত when
যেহেতু আপনার ফেন্সে অন্য কোনও ব্লক নেই।
read-string
তাদেরকে অষ্টাল হিসাবে ব্যাখ্যা করে: (read-string "08")
একটি ব্যতিক্রম ছোঁড়ে। Integer/valueOf
দশমিক হিসাবে তাদের আচরণ করে: (Integer/valueOf "08")
8 পর্যন্ত মূল্যায়ন করে
read-string
আপনি যদি একটি খালি স্ট্রিং বা "29px" এর মতো কিছু দেন তবে ব্যতিক্রম ছুঁড়ে
(defn parse-int [s]
(Integer. (re-find #"[0-9]*" s)))
user> (parse-int "10px")
10
user> (parse-int "10")
10
Integer/valueOf
এটি পূর্ণসংখ্যার কনস্ট্রাক্টরের চেয়ে ব্যবহার করার পরামর্শ দেওয়া হয় । ইন্টিজার শ্রেণি -128 এবং 127 এর মধ্যে অবজেক্ট তৈরিকে কমাতে মানগুলি ক্যাশে করে। : পূর্ণসংখ্যা Javadoc এই বর্ণনা পোস্টটি মতো stackoverflow.com/a/2974852/871012
এটি আমার পক্ষে প্রত্যক্ষভাবে কাজ করে, আরও অনেক সোজা এগিয়ে।
(পড়ার স্ট্রিং "123")
=> 123
আফাইক আপনার সমস্যার কোনও মানক সমাধান নেই। আমি মনে করি নিম্নলিখিতগুলির মতো কিছু ব্যবহার করে যা ব্যবহার করা clojure.contrib.str-utils2/replace
উচিত:
(defn str2int [txt]
(Integer/parseInt (replace txt #"[a-zA-Z]" "")))
1.5
এটি ছুড়ে ফেলে ... এবং এটি বিল্ট-ইন clojure.string/replace
ফাংশনটি ব্যবহার করে না ।
এই নিখুঁত নয়, কিন্তু এখানে কিছু filter
, Character/isDigit
এবং Integer/parseInt
। এটি ভাসমান পয়েন্ট সংখ্যাগুলির জন্য কাজ করবে না এবং ইনপুটটিতে কোনও অঙ্ক না থাকলে এটি ব্যর্থ হয়, সুতরাং আপনার সম্ভবত এটি পরিষ্কার করা উচিত। আমি আশা করি এটি করার একটি দুর্দান্ত উপায় আছে যাতে এত জাভা জড়িত না।
user=> (defn strToInt [x] (Integer/parseInt (apply str (filter #(Character/isDigit %) x))))
#'user/strToInt
user=> (strToInt "45px")
45
user=> (strToInt "45")
45
user=> (strToInt "a")
java.lang.NumberFormatException: For input string: "" (NO_SOURCE_FILE:0)
প্রয়োজনীয়তার সাথে আমি সম্ভবত কয়েকটি জিনিস যুক্ত করব:
হতে পারে এরকম কিছু:
(defn parse-int [v]
(try
(Integer/parseInt (re-find #"^\d+" (.toString v)))
(catch NumberFormatException e 0)))
(parse-int "lkjhasd")
; => 0
(parse-int (java.awt.Color. 4 5 6))
; => 0
(parse-int "a5v")
; => 0
(parse-int "50px")
; => 50
এবং তারপরে সম্ভবত এটি একটি বহু-পদ্ধতি তৈরির জন্য বোনাস পয়েন্ট যা ব্যবহারকারীর দ্বারা সরবরাহ করা ডিফল্ট 0 ছাড়া অন্যটিকে মঞ্জুরি দেয়।
স্নারবোটের উত্তরটি প্রসারিত করা:
(defn string->integer [s]
(when-let [d (re-find #"-?\d+" s)] (Integer. d)))
এই সংস্করণটি কোনও ব্যতিক্রম বাড়ানোর পরিবর্তে ইনপুটটিতে কোনও সংখ্যা না থাকলে শূন্য করে।
আমার প্রশ্নটি হ'ল নামটি "str-> int" সংক্ষেপে গ্রহণযোগ্য কিনা, বা যদি এর মতো জিনিসগুলি সর্বদা সম্পূর্ণ নির্দিষ্ট করা উচিত should
এছাড়াও (re-seq)
ফাংশনটি ব্যবহার করে ইনপুট স্ট্রিংয়ে থাকা সমস্ত নম্বর সমন্বিত স্ট্রিংয়ে ফেরতের মান প্রসারিত করতে পারে:
(defn convert-to-int [s]
(->> (re-seq #"\d" s)
(apply str)
(Integer.)))
(convert-to-int "10not123")
=> 10123
(type *1)
=> java.lang.Integer
একটি সংখ্যাটিতে একটি স্ট্রিংকে পার্স করার বিষয়ে প্রশ্ন জিজ্ঞাসা করে।
(number? 0.5)
;;=> true
সুতরাং উপরের দশমিকগুলি থেকে পাশাপাশি পার্স করা উচিত।
সম্ভবত এখন প্রশ্নের সঠিক উত্তর না দেওয়া, তবে সাধারণ ব্যবহারের জন্য আমি মনে করি যে এটি একটি নম্বর কিনা বা না (তাই "পিএক্স" অনুমোদিত নয়) এবং কলারকে শূন্যতার সাথে ফিরে আসার মাধ্যমে অ-সংখ্যাগুলি পরিচালনা করতে আপনি কঠোর হতে চান:
(defn str->number [x]
(when-let [num (re-matches #"-?\d+\.?\d*" x)]
(try
(Float/parseFloat num)
(catch Exception _
nil))))
এবং যদি আপনার ডোমেনের জন্য Float/parseFloat
পুট bigdec
বা অন্য কোনও কিছুর পরিবর্তে ফ্লোটগুলি সমস্যাযুক্ত হয় ।
অন্য যে কোনও ব্যক্তির জন্য একটি আরও সাধারণ স্ট্রিং আক্ষরিক সংখ্যায় বিভক্ত করার জন্য খুঁজছেন, এটি একটি স্ট্রিং যাতে অন্যান্য অ-সংখ্যাযুক্ত অক্ষর নেই। এই দুটি সেরা পন্থা:
জাভা ইন্টারপ ব্যবহার করে:
(Long/parseLong "333")
(Float/parseFloat "333.33")
(Double/parseDouble "333.3333333333332")
(Integer/parseInt "-333")
(Integer/parseUnsignedInt "333")
(BigInteger. "3333333333333333333333333332")
(BigDecimal. "3.3333333333333333333333333332")
(Short/parseShort "400")
(Byte/parseByte "120")
এটি যখন আপনার ব্যবহারের ক্ষেত্রে গুরুত্বপূর্ণ তখন আপনি সংখ্যাকে পার্স করতে চান ঠিক সেই ধরণের নিয়ন্ত্রণ করতে দেয়।
ক্লোজার ইডিএন পাঠক ব্যবহার করে:
(require '[clojure.edn :as edn])
(edn/read-string "333")
ব্যবহার ভিন্ন read-string
থেকে clojure.core
যা অবিশ্বস্ত ইনপুটের ব্যবহার করা নিরাপদ নয়, edn/read-string
যেমন ব্যবহারকারীর ইনপুট হিসাবে অনির্ভরযোগ্য ইনপুটের চালানোর জন্য নিরাপদ।
এটি প্রায়শই আরও সুবিধাজনক তবে জাভা ইন্টারপ যদি আপনার ধরণের নির্দিষ্ট নিয়ন্ত্রণের প্রয়োজন না হয়। এটি ক্লোজিউর যেমন যে কোনও সংখ্যক আক্ষরিক পার্স করতে পারে যেমন:
;; Ratios
(edn/read-string "22/7")
;; Hexadecimal
(edn/read-string "0xff")
এখানে সম্পূর্ণ তালিকা: https://www.rubberducking.com/2019/05/clojure-for-non-clojure-programmers.html#numbers
সাধারণ ক্ষেত্রে আপনি উপরে বর্ণিত অঙ্কের প্রথম স্ট্রিংটি বের করার জন্য কেবল একটি রেজেেক্স ব্যবহার করতে পারেন।
আপনার যদি আরও জটিল পরিস্থিতি থাকে তবে আপনি ইন্সটাপার্স লাইব্রেরিটি ব্যবহার করতে চাইতে পারেন:
(ns tst.parse.demo
(:use tupelo.test)
(:require
[clojure.string :as str]
[instaparse.core :as insta]
[tupelo.core :as t] ))
(t/refer-tupelo)
(dotest
(let [abnf-src "
size-val = int / int-px
int = digits ; ex '123'
int-px = digits <'px'> ; ex '123px'
<digits> = 1*digit ; 1 or more digits
<digit> = %x30-39 ; 0-9
"
tx-map {:int (fn fn-int [& args]
[:int (Integer/parseInt (str/join args))])
:int-px (fn fn-int-px [& args]
[:int-px (Integer/parseInt (str/join args))])
:size-val identity
}
parser (insta/parser abnf-src :input-format :abnf)
instaparse-failure? (fn [arg] (= (class arg) instaparse.gll.Failure))
parse-and-transform (fn [text]
(let [result (insta/transform tx-map
(parser text))]
(if (instaparse-failure? result)
(throw (IllegalArgumentException. (str result)))
result))) ]
(is= [:int 123] (parse-and-transform "123"))
(is= [:int-px 123] (parse-and-transform "123px"))
(throws? (parse-and-transform "123xyz"))))
(t/refer-tupelo)
ব্যবহারকারীকে না পেয়ে পরিবর্তে ব্যবহার করবেন কেন (:require [tupelo.core :refer :all])
?
refer-tupelo
এর পরে মডেল করা হয় refer-clojure
, এতে এতে সমস্ত কিছু অন্তর্ভুক্ত থাকে না (:require [tupelo.core :refer :all])
।