আমি কীভাবে জাভাতে ক্যামেলকেসকে মানব-পঠনযোগ্য নামগুলিতে রূপান্তর করব?


157

আমি এমন একটি পদ্ধতি লিখতে চাই যা ক্যামেলকেসকে মানব-পঠনযোগ্য নামে রূপান্তর করে।

পরীক্ষার কেসটি এখানে:

public void testSplitCamelCase() {
    assertEquals("lowercase", splitCamelCase("lowercase"));
    assertEquals("Class", splitCamelCase("Class"));
    assertEquals("My Class", splitCamelCase("MyClass"));
    assertEquals("HTML", splitCamelCase("HTML"));
    assertEquals("PDF Loader", splitCamelCase("PDFLoader"));
    assertEquals("A String", splitCamelCase("AString"));
    assertEquals("Simple XML Parser", splitCamelCase("SimpleXMLParser"));
    assertEquals("GL 11 Version", splitCamelCase("GL11Version"));
}

5
প্রথমত, আপনাকে রূপান্তরটির নিয়ম নির্দিষ্ট করতে হবে। উদাহরণস্বরূপ, কিভাবে PDFLoaderহয়ে যায় PDF Loader?
জর্ন শো-রোড

2
আমি সেই ফর্ম্যাটটিকে "পাস্কেলকেস" বলি। "উটকেস" এ প্রথম অক্ষরটি ছোট হাতের অক্ষরে লেখা উচিত। অন্তত যতটা বিকাশকারীরা উদ্বিগ্ন। msdn.microsoft.com/en-us/library/x2dbyw72(v=vs.71).aspx
মুহাদ

উত্তর:


337

এটি আপনার টেস্টকেসগুলির সাথে কাজ করে:

static String splitCamelCase(String s) {
   return s.replaceAll(
      String.format("%s|%s|%s",
         "(?<=[A-Z])(?=[A-Z][a-z])",
         "(?<=[^A-Z])(?=[A-Z])",
         "(?<=[A-Za-z])(?=[^A-Za-z])"
      ),
      " "
   );
}

এখানে একটি পরীক্ষার জোতা:

    String[] tests = {
        "lowercase",        // [lowercase]
        "Class",            // [Class]
        "MyClass",          // [My Class]
        "HTML",             // [HTML]
        "PDFLoader",        // [PDF Loader]
        "AString",          // [A String]
        "SimpleXMLParser",  // [Simple XML Parser]
        "GL11Version",      // [GL 11 Version]
        "99Bottles",        // [99 Bottles]
        "May5",             // [May 5]
        "BFG9000",          // [BFG 9000]
    };
    for (String test : tests) {
        System.out.println("[" + splitCamelCase(test) + "]");
    }

এটি শূন্য স্থানের সন্ধান করার জন্য লুকবিহ্যান্ড এবং লুকওয়ারওয়ার্ডের সাথে শূন্য দৈর্ঘ্যের ম্যাচিং রেজেক্স ব্যবহার করে। মূলত এখানে 3 টি নিদর্শন রয়েছে এবং আমি String.formatএগুলি আরও পঠনযোগ্য করে তোলার জন্য একত্রে ব্যবহার করি ।

তিনটি নিদর্শন হ'ল:

আমার পিছনে ইউসি, ইউসি আমার সামনে এলসি অনুসরণ করে

  XMLParser   AString    PDFLoader
    /\        /\           /\

আমার পিছনে নন-ইউসি, আমার সামনে ইউসি

 MyClass   99Bottles
  /\        /\

আমার পিছনে চিঠি, আমার সামনে নন-চিঠি

 GL11    May5    BFG9000
  /\       /\      /\

তথ্যসূত্র

সম্পর্কিত প্রশ্নগুলি

বিভক্ত করতে শূন্য-দৈর্ঘ্যের মিলের দর্শনীয় ব্যবহারগুলি:


1
ধারণাটি সি # তেও একইভাবে কাজ করে (একই নিয়মিত প্রকাশের সাথে, তবে অবশ্যই কিছুটা নিয়মিত-এক্সপ্রেশন ফ্রেমওয়ার্ক অবশ্যই)। চমৎকার কাজ. ধন্যবাদ!
জিএমএম

পাইথনে আমার পক্ষে কাজ করছে বলে মনে হয় না, এটি কারণ হতে পারে রেজেক্স ইঞ্জিনটি একই নয়। আমাকে কম মার্জিত কিছু করার চেষ্টা করতে হবে, আমি ভীত। :)
মারিওভাইলাস

2
কেউ দয়া করে টেস্টকেসের ক্ষেত্রে এবং% s এর সাথে% s |% s |% এর অর্থ কী তা ব্যাখ্যা করতে পারেন?
Ari53nN3o

1
@ Ari53nN3o: " %s" এর String.format(String format, args...)যুক্তিগুলির স্থানধারক for আপনি সূচকেও কল করতে পারেন:String.format("%$1s|%$2s|%$3s", ...
মিঃ পলিহর্ল

এটি সি # তে কীভাবে কাজ করবে? relaceAllস্ট্রিংটিতে এর সাথে " ." বিভাজন যুক্ত করতে চাইছি এমনও নেই ।
সরোজানন্দ

119

আপনি এটি ব্যবহার করে করতে পারেন org.apache.commons.lang.StringUtils

StringUtils.join(
     StringUtils.splitByCharacterTypeCamelCase("ExampleTest"),
     ' '
);

9
এই সমাধানটি সর্বাধিক উত্সাহিত একের চেয়ে অনেক ভাল কারণ: ক) এটি চাকাটি পুনরায় উদ্ভাবন করে না: কমন্স-ল্যাং একটি ডি-ফ্যাক্টো স্ট্যান্ডার্ড এবং এটি সূক্ষ্মভাবে কাজ করে, খুব কার্য সম্পাদনকে কেন্দ্র করে। খ) যখন রূপান্তরটি অনেকবার করা হয় তখন এই পদ্ধতিটি রেজেক্স-ভিত্তিকের চেয়ে অনেক দ্রুত হয়: পূর্বোক্ত পরীক্ষাগুলি ১০০,০০০ বার সম্পাদন করার জন্য এটি আমার মাপকাঠি: ge `` রেজেক্স-ভিত্তিক পদ্ধতিটি 4820 মিলিসেকেন্ড ///// গ্রহণ করেছিল ///// কমন্স-ল্যাং-ভিত্তিক পদ্ধতিটি 232 মিলিসেকেন্ডে নিয়েছিল re `` যা রেজেক্স ব্যবহারের চেয়ে প্রায় 20 গুণ বেশি দ্রুত !!!!
ক্লিন্ট ইস্টউড

2
আমি অবশ্যই এই সম্পর্কে ক্লিন্টের সাথে একমত, এটি গ্রহণযোগ্য উত্তর হওয়া উচিত। পারফরম্যান্স একটি জিনিস তবে যুদ্ধ-পরীক্ষিত লাইব্রেরি ব্যবহার করা অবশ্যই একটি ভাল প্রোগ্রামিং অনুশীলন।
জুলিয়ান

1
অথবা জাভা 8 এর স্ট্রিং.জোঁইন () পদ্ধতিটি ব্যবহার করে: স্ট্রিং.জোঁইন ("", স্ট্রিংইটিলস.স্প্লিটবাইচ্যাকারটাইপক্যামেলকেস ("উদাহরণস্বরূপ"));
dk7

আপনি কীভাবে ক্লিন্ট ইস্টউডের সাথে একমত হতে পারেন না? :)
দানিজেলা

19

পরিষ্কার এবং খাটো সমাধান:

StringUtils.capitalize(StringUtils.join(StringUtils.splitByCharacterTypeCamelCase("yourCamelCaseText"), StringUtils.SPACE)); // Your Camel Case Text

assertপ্রশ্নের প্রথমটিতে প্রদর্শিত হিসাবে , মূলধন পছন্দসই নয়।
স্লার্তিদান

বাগটি ধরার জন্য ধন্যবাদ, উত্তরটি আপডেট করবে।
সাহিল ছাবার

10

আপনি যদি "জটিল" রেজেক্স পছন্দ করেন না এবং দক্ষতা সম্পর্কে মোটেই বিরক্ত না হন তবে তিনটি পর্যায়ে একই প্রভাব অর্জনের জন্য আমি এই উদাহরণটি ব্যবহার করেছি।

String name = 
    camelName.replaceAll("([A-Z][a-z]+)", " $1") // Words beginning with UC
             .replaceAll("([A-Z][A-Z]+)", " $1") // "Words" of only UC
             .replaceAll("([^A-Za-z ]+)", " $1") // "Words" of non-letters
             .trim();

এটি উপরের সমস্ত পরীক্ষার কেসগুলিতে পাস করে, অঙ্কগুলি সহ।

আমি যেমন বলেছি, এখানে অন্য কয়েকটি উদাহরণে নিয়মিত প্রকাশের মতো এটি ব্যবহার করা ঠিক ততটা ভাল নয় - তবে কেউ এটির পক্ষে দরকারী well


1
ধন্যবাদ, এটি দুর্দান্ত ছিল। আমি একটি জাভাস্ক্রিপ্ট সংস্করণ তৈরি করেছি ।
মিঃ পলিহর্ল

আপনি যদি কোনও রেইজেক্স লাইব্রেরি / সরঞ্জামের সাথে কাজ করছেন যা লুকবিহিন্ড / লুকফোরওয়ার্ডের মতো নয় (গোলংয়ের রেজিপ্সেপ প্যাকেজের মতো) কাজ করে তবে এই পথে যাওয়ার একমাত্র উপায়। চমৎকার কাজ.
এমডিহটকাট 20'15

6

আপনি org.modeshape.common.text.Inflector ব্যবহার করতে পারেন ।

বিশেষ করে:

String humanize(String lowerCaseAndUnderscoredWords,
    String... removableTokens) 

প্রথম শব্দের মূলধন করে এবং "_আইডি" এবং কোনও সরবরাহযোগ্য অপসারণযোগ্য টোকেনকে অনুসরণ করে স্পেস এবং স্ট্রিপগুলিতে আন্ডারস্কোরগুলিকে রূপান্তরিত করে।

ম্যাভেন আর্টিফ্যাক্টটি হ'ল: org.modeshape: Modeshpe- সাধারণ: 2.3.0. ফাইনাল

জেবস সংগ্রহস্থলের উপর: https://repository.jboss.org/nexus/content/repositories/releases

এখানে জার ফাইলটি: https://repository.jboss.org/nexus/content/repositories/releases/org/modeshape/modeshape-common/2.3.0.Final/modeshape-common-2.3.0.Final.jar


1

নিম্নলিখিত Regex শব্দের ভিতরে রাজধানী সনাক্ত করতে ব্যবহার করা যেতে পারে:

"((?<=[a-z0-9])[A-Z]|(?<=[a-zA-Z])[0-9]]|(?<=[A-Z])[A-Z](?=[a-z]))"

এটি প্রতিটি মূলধনীর সাথে মেলে, এটি একটি অ-মূলধন চিঠি বা অঙ্কের পরে বা পরে একটি ছোট কেস লেটার এবং একটি চিঠির পরে প্রতিটি অঙ্ক থাকে।

আমার জাভা দক্ষতার বাইরে কীভাবে কোনও স্থান সন্নিবেশ করা যায় =)

ডিজিট কেস এবং পিডিএফ লোডার কেস অন্তর্ভুক্ত করার জন্য সম্পাদিত।


@ ইয়ানিভ: আমি সবেমাত্র অঙ্কগুলি দেখেছি ... এটি বিষয়গুলি আরও জটিল করে তুলতে পারে। সম্ভবত এগুলিকে ধরার জন্য আর একটি রেইজেক্স হ'ল সহজ উপায়।
জেনস

@Jens: এটা ম্যাচ হবে Lমধ্যে PDFLoader?
জর্ন শো-রোড

(? <= [a-z0-9]) [A-Z0-9] সম্পর্কে কীভাবে?
ইয়ানিভ

3
এখন, আমি আপনার রেগেক্স দক্ষতার ব্যাপক প্রশংসা করি, তবে আমি এটি বজায় রাখতে পছন্দ করি না।
ক্রিস নাইট

1
@ ক্রিস: হ্যাঁ, সত্য। রিজেক্স কেবল লেখার জন্য ভাষা বেশি। =) যদিও এই নির্দিষ্ট অভিব্যক্তিটি পড়া খুব কঠিন নয়, যদি আপনি |"বা" হিসাবে পড়েন । ঠিক আছে ... হতে পারে ... আমি
খারাপটি

1

আমি মনে করি আপনাকে স্ট্রিং দিয়ে পুনরাবৃত্তি করতে হবে এবং ছোট হাতের থেকে বড় হাতের থেকে বড় হাতের থেকে ছোট হাতের থেকে ছোট হাতের থেকে বর্ণানুক্রমিক থেকে, সংখ্যায় বর্ণমালা অনুসারে পরিবর্তনগুলি সনাক্ত করতে হবে। প্রতিটি পরিবর্তনে আপনি একটি ব্যতিক্রম সহ একটি স্থান সন্নিবেশ করান তবে: উপরের থেকে পরিবর্তনের ক্ষেত্রে আপনি ছোট অক্ষরের আগে স্পেস সন্নিবেশ করান।


1

এটি নেট মধ্যে কাজ করে ... আপনার পছন্দ অনুসারে অনুকূলিত করুন। আমি মন্তব্য যুক্ত করেছি যাতে আপনি বুঝতে পারবেন প্রতিটি টুকরা কী করছে। (RegEx বোঝা কঠিন হতে পারে)

public static string SplitCamelCase(string str)
{
    str = Regex.Replace(str, @"([A-Z])([A-Z][a-z])", "$1 $2");  // Capital followed by capital AND a lowercase.
    str = Regex.Replace(str, @"([a-z])([A-Z])", "$1 $2"); // Lowercase followed by a capital.
    str = Regex.Replace(str, @"(\D)(\d)", "$1 $2"); //Letter followed by a number.
    str = Regex.Replace(str, @"(\d)(\D)", "$1 $2"); // Number followed by letter.
    return str;
}

0

রেকর্ডের জন্য, এখানে প্রায় (*) সামঞ্জস্যপূর্ণ স্কালা সংস্করণ রয়েছে:

  object Str { def unapplySeq(s: String): Option[Seq[Char]] = Some(s) }

  def splitCamelCase(str: String) =
    String.valueOf(
      (str + "A" * 2) sliding (3) flatMap {
        case Str(a, b, c) =>
          (a.isUpper, b.isUpper, c.isUpper) match {
            case (true, false, _) => " " + a
            case (false, true, true) => a + " "
            case _ => String.valueOf(a)
          }
      } toArray
    ).trim

একবার সঙ্কলিত হলে এটি সরাসরি জাভা থেকে ব্যবহার করা যেতে পারে যদি সংশ্লিষ্ট স্কালা-লাইব্রেরি.জার ক্লাসপথে থাকে।

(*) এটি যে ইনপুটটির জন্য "GL11Version"ফিরে আসে তার ব্যর্থ হয় "G L11 Version"


0

আমি পলিজেনিউব্রিকেন্টস থেকে রেজেক্স নিয়েছি এবং এটিকে অবজেক্টগুলিতে একটি এক্সটেনশন পদ্ধতিতে পরিণত করেছি:

    /// <summary>
    /// Turns a given object into a sentence by:
    /// Converting the given object into a <see cref="string"/>.
    /// Adding spaces before each capital letter except for the first letter of the string representation of the given object.
    /// Makes the entire string lower case except for the first word and any acronyms.
    /// </summary>
    /// <param name="original">The object to turn into a proper sentence.</param>
    /// <returns>A string representation of the original object that reads like a real sentence.</returns>
    public static string ToProperSentence(this object original)
    {
        Regex addSpacesAtCapitalLettersRegEx = new Regex(@"(?<=[A-Z])(?=[A-Z][a-z]) | (?<=[^A-Z])(?=[A-Z]) | (?<=[A-Za-z])(?=[^A-Za-z])", RegexOptions.IgnorePatternWhitespace);
        string[] words = addSpacesAtCapitalLettersRegEx.Split(original.ToString());
        if (words.Length > 1)
        {
            List<string> wordsList = new List<string> { words[0] };
            wordsList.AddRange(words.Skip(1).Select(word => word.Equals(word.ToUpper()) ? word : word.ToLower()));
            words = wordsList.ToArray();
        }
        return string.Join(" ", words);
    }

এটি সবকিছুকে পাঠযোগ্য বাক্যে পরিণত করে। এটি পাস করা অবজেক্টের একটি টসস্ট্রিং করে। তারপরে এটি স্ট্রিংকে বিভক্ত করার জন্য পলিজেনিউব্রিকেন্টস দ্বারা প্রদত্ত রেজেক্স ব্যবহার করে। তারপরে এটি প্রথম শব্দ এবং কোনও সংক্ষিপ্ত শব্দ ছাড়া প্রতিটি শব্দের ToLowers। ভেবেছি এটি কারও পক্ষে কার্যকর হতে পারে।


-2

আমি কোনও রেজেক্স নিনজা নই, সুতরাং আমি বর্তমান পজিশনের সূচীগুলি পরীক্ষা করে এবং পূর্ববর্তী অবস্থানটি রেখে স্ট্রিংটি দিয়ে পুনরাবৃত্তি করতাম। যদি বর্তমান অবস্থানটি মূল অক্ষর হয় তবে আমি পূর্ববর্তী অবস্থানের পরে একটি স্থান সন্নিবেশ করতাম এবং প্রতিটি সূচকে বৃদ্ধি করতাম।


2
Psssh! তাতে মজা কোথায়?
ভবুলিংগার

-3

http://code.google.com/p/inflection-js/

ক্যামেলকেস স্ট্রিং নেওয়ার জন্য এবং এটিকে একটি মানব পাঠযোগ্য স্ট্রিংতে রূপান্তর করার জন্য আপনি স্ট্রিং.ফাউন্ডসর ()। হিউম্যানাইজ () পদ্ধতিগুলিকে চেইন করতে পারেন।


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