স্ট্রিং.রেপ্লেস ডাবল ব্যাকস্ল্যাশ সহ সমস্ত একক ব্যাকস্ল্যাশ


122

আমি String \something\এটি String \\something\\ব্যবহারে রূপান্তরিত করার চেষ্টা করছি replaceAllতবে আমি সমস্ত ধরণের ত্রুটি পেতে থাকি। আমি ভেবেছিলাম এটিই সমাধান:

theString.replaceAll("\\", "\\\\");

তবে এটি নীচের ব্যতিক্রম দেয়:

java.util.regex.PatternSyntaxException: Unexpected internal error near index 1

উত্তর:


204

String#replaceAll()হিসেবে যুক্তি ব্যাখ্যা করে রেগুলার এক্সপ্রেশন\একটি পালাবার চরিত্র উভয় String এবং regex। রেইজেক্সের জন্য আপনাকে এটিকে দ্বিগুণভাবে পালাতে হবে:

string.replaceAll("\\\\", "\\\\\\\\");

তবে আপনার অগত্যা এটির জন্য রেজেেক্সের প্রয়োজন হবে না, কেবল কারণ আপনি সঠিক চরিত্র অনুসারে অক্ষর প্রতিস্থাপন করতে চান এবং আপনার এখানে নিদর্শনগুলির প্রয়োজন নেই। সুতরাং String#replace()যথেষ্ট করা উচিত:

string.replace("\\", "\\\\");

আপডেট : মতামত অনুসারে, আপনি জাভাস্ক্রিপ্ট প্রসঙ্গে স্ট্রিংটি ব্যবহার করতে চান বলে মনে হচ্ছে। আপনি StringEscapeUtils#escapeEcmaScript()আরও অক্ষর আবরণ পরিবর্তে সম্ভবত আরও ভাল ব্যবহার করতে চাই ।


প্রকৃতপক্ষে, এটি একটি জাভাস্ক্রিপ্ট এএসটি-তে ব্যবহৃত হয় যা উত্সে ফিরে রূপান্তর করা উচিত। আপনার সমাধান কাজ করে। ধন্যবাদ!
ফ্রাঙ্ক গ্রেনেভেল্ড

2
আপনি যদি String#replaceAll()যাইহোক ব্যবহার করতে চান, আপনি ম্যাচার # রেট রিপ্লেসমেন্ট () এর সাথে প্রতিস্থাপনের স্ট্রিংটি উদ্ধৃত করতে পারেন :theString.replaceAll("\\", Matcher.quoteReplacement("\\\\"));
phse

ম্যাচার.কোটরেপ্লেসমেন্ট (...) একটি ভাল উপায়! দয়া করে দেখুন দয়ােমার উত্তর!
হার্টমুট পি।

14

এই ধরণের ঝামেলা এড়াতে, আপনি (যা নিয়মিত প্রকাশ করে) এর replaceপরিবর্তে replaceAll(যা একটি সরল স্ট্রিং নেয়) ব্যবহার করতে পারেন । আপনার এখনও ব্যাকস্ল্যাশগুলি এড়াতে হবে, তবে নিয়মিত প্রকাশের সাথে প্রয়োজনীয় বন্য পদ্ধতিতে নয়।


10

টিএলডিআর: theString = theString.replace("\\", "\\\\");পরিবর্তে ব্যবহার করুন।


সমস্যা

replaceAll(target, replacement)এর জন্য targetএবং আংশিকভাবে নিয়মিত এক্সপ্রেশন (রেজেক্স) সিনট্যাক্স ব্যবহার করে replacement

সমস্যাটি হ'ল \রেগেক্সে এটি বিশেষ চরিত্র (এটি অঙ্কটি \dউপস্থাপনের মতো ব্যবহার করা যেতে পারে ) এবং স্ট্রিং আক্ষরিক ক্ষেত্রে (এটি "\n"লাইন বিভাজককে উপস্থাপন \"করতে বা ডাবল উদ্ধৃতি চিহ্ন থেকে বেরিয়ে আসার জন্য ব্যবহার করা যেতে পারে যা সাধারণত স্ট্রিং লিটারেলের শেষের প্রতিনিধিত্ব করে)।

এই উভয় ক্ষেত্রেই তৈরি করার জন্য \প্রতীক আমরা করতে অব্যাহতি এটা (এটিকে পরিবর্তে বিশেষ অক্ষর আভিধানিক) অতিরিক্ত স্থাপন দ্বারা \এটা আগে (যেমন আমরা অব্যাহতি "মাধ্যমে স্ট্রিং লিটারেল মধ্যে \")।

সুতরাং targetপ্রতিনিধিত্বকারী \প্রতীককে রেজেক্সের জন্য ধারণ করতে হবে \\, এবং এই জাতীয় পাঠ্যের প্রতিনিধিত্বকারী স্ট্রিংয়ের মতো দেখতে হবে "\\\\"

সুতরাং আমরা \দুবার পালিয়েছি :

  • একবার রেগেক্সে \\
  • স্ট্রিং আক্ষরিক একবারে "\\\\"(প্রতিটি \হিসাবে প্রদর্শিত হয় "\\")।

ক্ষেত্রে replacement \এছাড়াও বিশেষ। এটি আমাদের অন্যান্য বিশেষ চরিত্র থেকে বাঁচতে দেয় $যা চিহ্নিতকরণের মাধ্যমে $x, রেগেক্সের সাথে মিলে যাওয়া এবং ক্যাপচারিত গোষ্ঠী অনুসারে ডেটা অংশ ব্যবহার করার অনুমতি দেয় x, যেমন "012".replaceAll("(\\d)", "$1$1")প্রতিটি অঙ্কের সাথে মিলে যায়, এটি গ্রুপ 1-এ ধারণ $1$1করবে এবং এর দুটি অনুলিপি দিয়ে এটি প্রতিস্থাপন করবে (এটি এটির সদৃশ করবে) যার ফলস্বরূপ "001122"

আবার, আক্ষরিক replacementপ্রতিনিধিত্ব \করতে আমাদের এটিকে অতিরিক্ত দিয়ে পালাতে হবে \যার অর্থ:

  • প্রতিস্থাপনে অবশ্যই দুটি ব্যাকস্ল্যাশ অক্ষর রাখা উচিত \\
  • এবং স্ট্রিং আক্ষরিক যা \\দেখতে দেখতে উপস্থাপন করে"\\\\"

তবে যেহেতু আমরা দুটি ব্যাকস্ল্যাশ replacementধরে রাখতে চাই আমাদের প্রয়োজন (প্রত্যেকে একে একে প্রতিনিধিত্ব করে )।"\\\\\\\\"\"\\\\"

সুতরাং সংস্করণ replaceAllমত দেখতে পারেন

replaceAll("\\\\", "\\\\\\\\");

আরও সহজ উপায়

জীবনকে আরও সহজ করার জন্য জাভা স্বয়ংক্রিয়ভাবে পাঠ্য targetএবং replacementঅংশগুলিতে পালাতে সরঞ্জাম সরবরাহ করে । সুতরাং এখন আমরা কেবল স্ট্রিংগুলিতে ফোকাস করতে পারি এবং রেজেক্স সিনট্যাক্সটি ভুলে যেতে পারি:

replaceAll(Pattern.quote(target), Matcher.quoteReplacement(replacement))

আমাদের ক্ষেত্রে যা দেখতে পারে

replaceAll(Pattern.quote("\\"), Matcher.quoteReplacement("\\\\"))

আর ভালো

আমাদের যদি সত্যই দরকার হয় না তবে রেগেক্স সিনট্যাক্স সহায়তা একেবারেই জড়িত replaceAllহতে দেয়। পরিবর্তে ব্যবহার করতে দেয় replace। উভয় পদ্ধতি প্রতিস্থাপন করবে সব target গুলি কিন্তু replaceRegex সিনট্যাক্স সঙ্গে যুক্ত নয়। সুতরাং আপনি সহজভাবে লিখতে পারে

theString = theString.replace("\\", "\\\\");

7

এটি নিয়মিত প্রকাশ হিসাবে আপনার প্রথম আর্গুমেন্টে (পালানো) ব্যাকস্ল্যাশ এড়াতে হবে। প্রতিস্থাপন (দ্বিতীয় যুক্তি - দেখুন ম্যাচার # রিপ্লেসমেন্ট (স্ট্রিং) দেখুন ) এর ব্যাকস্ল্যাশগুলিরও বিশেষ অর্থ রয়েছে, সুতরাং আপনাকে সেগুলি প্রতিস্থাপন করতে হবে:

theString.replaceAll("\\\\", "\\\\\\\\");

3

হ্যাঁ ... যতক্ষণ না রেইগেক্স সংকলক আপনার দেওয়া প্যাটার্নটি দেখে তা কেবল একটি একক ব্যাকস্ল্যাশ দেখতে পায় (যেহেতু জাভা এর লেক্সার ডাবল ব্যাকচ্যাকটিকে একটিতে রূপান্তরিত করেছে)। আপনার "\\\\"সাথে "\\\\"এটি প্রতিস্থাপন করা দরকার , বিশ্বাস করুন বা না করুন! জাভা সত্যিই একটি ভাল কাঁচা স্ট্রিং সিনট্যাক্স প্রয়োজন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.