ক্যামেলকেসকে সাপ_কেসে রূপান্তর করতে মার্জিত পাইথন ফাংশন?


333

উদাহরণ:

>>> convert('CamelCase')
'camel_case'

28
অন্য দিকে রূপান্তর করতে, এই অন্যান্য স্ট্যাকওভারফ্লো প্রশ্নটি দেখুন।
নাথান

10
এনবি এটি NotCamelCaseতবেthisIs
ম্যাট রিচার্ডস

5
@ ম্যাটরিচার্ডস এটি বিরোধের বিষয়। উইকি
NO_NAME

@ ম্যাটআরিচার্ডস উদাহরণস্বরূপ জাভাতে তারা উভয়ই ব্যবহার করেন, ক্যামেলকেস ক্লাস সংজ্ঞা নামকরণের জন্য ব্যবহৃত হয়, অন্যদিকে উটকেস আদ্যক্ষর ভেরিয়েবলের নামকরণের জন্য ব্যবহৃত হয়।
অন্ধকারহীন

উত্তর:


796

সাপের ক্ষেত্রে উটের মামলা

import re

name = 'CamelCaseName'
name = re.sub(r'(?<!^)(?=[A-Z])', '_', name).lower()
print(name)  # camel_case_name

আপনি যদি অনেক বার এটি করেন এবং উপরেরটি ধীর গতিতে থাকে তবে আগে থেকেই রেগেক্স সংকলন করুন:

pattern = re.compile(r'(?<!^)(?=[A-Z])')
name = pattern.sub('_', name).lower()

আরও উন্নত কেস বিশেষভাবে পরিচালনা করার জন্য (এটি আর ফেরানো যাবে না):

def camel_to_snake(name):
  name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
  return re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()

print(camel_to_snake('camel2_camel2_case'))  # camel2_camel2_case
print(camel_to_snake('getHTTPResponseCode'))  # get_http_response_code
print(camel_to_snake('HTTPResponseCodeXYZ'))  # http_response_code_xyz

উটের মামলায় সাপের মামলা

name = 'snake_case_name'
name = ''.join(word.title() for word in name.split('_'))
print(name)  # SnakeCaseName

1
এই সমাধানগুলি এই ক্ষেত্রে ব্যর্থ হয়: _পট_মথোড, __ সেরা__মঠোড, _টেষ্ট, এইচটিটিপিএসপিসনস কোড, __ ক্যামেলকেস এবং _ ক্যামেল_কেস।
ফ্রিগনু

6
বিপরীতটি কেমন? একটি রূপান্তর not_camel_caseকরতে notCamelCaseএবং / অথবা NotCamelCase?
এক্স

9
যেমন উট_কেস রূপান্তর করার সময় ডাবল আন্ডারস্কোরগুলি এড়ানোর জন্য, এই লাইনটি যুক্ত করুন:s2.replace('__', '_')
মার্কাস আহলবার্গ

2
নোট করুন এটি খুব বিপরীতমুখী নয়। getHTTPResponseCode get_h_t_t_t_p_response_code এ রূপান্তর করা উচিত। getHttpResponseCode get_http_response_code
K2xL

4
@ আনমোলসিংহ জাগি প্রথম রেজেেক্স একটি সংক্ষিপ্ত রূপের প্রান্ত কেস পরিচালনা করে যা অন্য একটি শব্দের দ্বারা অনুসরণ করা হয় (যেমন "HTTPResponse" -> "HTTP_Response") বা প্রাথমিক ছোট শব্দটির আরও সাধারণ ক্ষেত্রে একটি মূলধন শব্দের পরে (যেমন "getResponse" -> " get_Response "। দ্বিতীয় রেজেক্স দুটি অ-সংক্ষেপণ (যেমন" রেসপন্সকোড "->" রেসপন্স_কোড ") এর সাধারণ কেসটি পরিচালনা করে এবং তারপরে সবকিছুকে ছোট করে রাখার চূড়ান্ত কল হয় Thus > "get_http_response_code"
জেফ মোসার

188

প্যাকেজ সূচীতে একটি প্রতিচ্ছবি পাঠাগার রয়েছে যা আপনার জন্য এই জিনিসগুলি পরিচালনা করতে পারে। এই ক্ষেত্রে, আপনি খুঁজছেন চাই inflection.underscore():

>>> inflection.underscore('CamelCase')
'camel_case'

44
আমি বুঝতে পারি না যে লোকেরা যখন এই কাজটি সম্পাদন করে এমন দুর্দান্ত গ্রন্থাগার রয়েছে তখন তারা কাস্টম ফাংশনগুলির ব্যবহারের বিষয়ে কেন ভোট দিচ্ছে। আমাদের চাকা পুনর্নবীকরণ করা উচিত নয়।
Oden

88
@ ওডেন সম্ভবত একক-লাইনের ফাংশনের কাজ করার জন্য একটি সম্পূর্ণ নতুন নির্ভরতা যুক্ত করার কারণে ওভার-কিল ভঙ্গুর?
সিসিল কারি

11
উদাহরণস্বরূপ, নিশ্চিত যে এটি ওভারকিল। বৃহত্তর অ্যাপ্লিকেশন জুড়ে, চাকাটি পুনরায় উদ্ভাবন এবং অবিচ্ছিন্ন করার দরকার নেই।
ব্র্যাড কোচ

11
রেজেক্সস "সিঙ্গল লাইনে" প্রচুর পরিমাণে ফিরে আসে, এ কারণেই এটি যথাযথ পরীক্ষার সাথে এক লাইনের চেয়ে অনেক বেশি।
স্টুডিজ

12
@ সিসিলকিউরি: আমি নিশ্চিত যে আপনি দুর্দান্ত প্রোগ্রামার, তবে আমি নিশ্চিত নই যে আপনি বিবেচনা করেন নি এমন কেস নেই - উদাহরণস্বরূপ অন্য উত্তরগুলি এখানে দেখুন। এজন্য আমি সবসময় একটি লাইব্রেরি বেছে নেব, কারণ এটি কেবল আমার চেয়ে অনেক বেশি দেবের সমষ্টি অভিজ্ঞতা।
মাইকেল শ্যাপার

104

আমি জানি না কেন এগুলি এত জটিল।

বেশিরভাগ ক্ষেত্রে, সাধারণ অভিব্যক্তিটি ([A-Z]+)কৌশলটি করবে

>>> re.sub('([A-Z]+)', r'_\1','CamelCase').lower()
'_camel_case'  
>>> re.sub('([A-Z]+)', r'_\1','camelCase').lower()
'camel_case'
>>> re.sub('([A-Z]+)', r'_\1','camel2Case2').lower()
'camel2_case2'
>>> re.sub('([A-Z]+)', r'_\1','camelCamelCase').lower()
'camel_camel_case'
>>> re.sub('([A-Z]+)', r'_\1','getHTTPResponseCode').lower()
'get_httpresponse_code'

প্রথম চরিত্রটিকে উপেক্ষা করার জন্য কেবল পিছনে চেহারা যুক্ত করুন (?!^)

>>> re.sub('(?!^)([A-Z]+)', r'_\1','CamelCase').lower()
'camel_case'
>>> re.sub('(?!^)([A-Z]+)', r'_\1','CamelCamelCase').lower()
'camel_camel_case'
>>> re.sub('(?!^)([A-Z]+)', r'_\1','Camel2Camel2Case').lower()
'camel2_camel2_case'
>>> re.sub('(?!^)([A-Z]+)', r'_\1','getHTTPResponseCode').lower()
'get_httpresponse_code'

আপনি যদি ALLCaps all_caps এ পৃথক করতে চান এবং আপনার স্ট্রিংয়ের মধ্যে সংখ্যাগুলি আশা করতে চান তবে আপনাকে কেবল দুটি পৃথক রান করার দরকার নেই |এই অভিব্যক্তিটি ((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z]))বইয়ের প্রতিটি দৃশ্যের প্রায়শই পরিচালনা করতে পারে

>>> a = re.compile('((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z]))')
>>> a.sub(r'_\1', 'getHTTPResponseCode').lower()
'get_http_response_code'
>>> a.sub(r'_\1', 'get2HTTPResponseCode').lower()
'get2_http_response_code'
>>> a.sub(r'_\1', 'get2HTTPResponse123Code').lower()
'get2_http_response123_code'
>>> a.sub(r'_\1', 'HTTPResponseCode').lower()
'http_response_code'
>>> a.sub(r'_\1', 'HTTPResponseCodeXYZ').lower()
'http_response_code_xyz'

এটি সর্বোপরি জটিল হওয়া উচিত নয় এমন সমাধান ব্যবহার করুন যা আপনার প্রয়োজন অনুসারে সবচেয়ে বেশি উপযুক্ত তা নির্ভর করে।

nJoy!


1
শেষ পুনরাবৃত্তিটি সবচেয়ে চালাক, আইএমও। এটি প্রতিটি শব্দের শুরুতে কেবলমাত্র একক চরিত্রকে প্রতিস্থাপন করছে তা বুঝতে আমাকে একটু সময় লাগল - এবং এটি কেবল কারণটি ছিল যে আমি নিজের সাথে এসেছি এমন পদ্ধতির চেয়ে আলাদা ছিল। সুন্দরভাবে সম্পন্ন.
জাস্টিন মিলার

2
(?!^)অভিব্যক্তিটিকে লুক-ব্যাক বলে ডাকে আমি হতবাক হয়ে গেলাম । আমি যদি কিছু মিস করি না তবে আমরা এখানে যা চাই তা হ'ল নেতিবাচক চেহারা যা হিসাবে প্রকাশ করা উচিত (?<!^)। কারণগুলির জন্য আমি বুঝতে পারি না আপনার নেতিবাচক চেহারা এগিয়ে (?!^)
চলেছে

7
এটি প্রাইসিংকে আন্ডারস্কোরগুলি ভালভাবে পরিচালনা করতে পারে না: "Camel2WARNING_Case_CASE"হয়ে যায় "camel2_warning_case__case"। এটি সমাধানের জন্য আপনি একটি (?<!_)নেতিবাচক চেহারাটি জুড়তে পারেন : re.sub('((?<=[a-z0-9])[A-Z]|(?!^)(?<!_)[A-Z](?=[a-z]))', r'_\1', "Camel2WARNING_Case_CASE").lower() রিটার্ন 'camel2_warning_case_case'
ভাগ্যডোনাল্ড

@ অ্যাপটারিক্স আপনি ঠিক বলেছেন, (?!^)ভুলভাবে "পিছনে চেহারা" বলা হত এবং পরিবর্তে তাকে নেতিবাচক লুক হেড বলা উচিত ছিল । হিসাবে এই সুন্দর ব্যাখ্যা শো, নেতিবাচক lookaheads সাধারণত আসে পরে অভিব্যক্তি তোমার পাশে অনুসন্ধান করা হচ্ছে। সুতরাং আপনি (?!^)" ''কোথায় <start of string>অনুসরণ করেন না " এটি হিসাবে ভাবতে পারেন । প্রকৃতপক্ষে, একটি নেতিবাচক চেহারা পিছনেও কাজ করে: আপনি (?<!^)" আগে ''কোথায় <start of string>নেই " এটি হিসাবে ভাবতে পারেন ।
নাথানিয়েল জোন্স


11

ব্যক্তিগতভাবে আমি নিশ্চিত না যে পাইথনে নিয়মিত প্রকাশগুলি ব্যবহার করে যে কোনও কিছুই মার্জিত হিসাবে বর্ণনা করা যায়। এখানে বেশিরভাগ উত্তর কেবল "কোড গল্ফ" টাইপ আর আর ট্রিকস করছে। মার্জিত কোডিং সহজেই বোঝার কথা।

def to_snake_case(not_snake_case):
    final = ''
    for i in xrange(len(not_snake_case)):
        item = not_snake_case[i]
        if i < len(not_snake_case) - 1:
            next_char_will_be_underscored = (
                not_snake_case[i+1] == "_" or
                not_snake_case[i+1] == " " or
                not_snake_case[i+1].isupper()
            )
        if (item == " " or item == "_") and next_char_will_be_underscored:
            continue
        elif (item == " " or item == "_"):
            final += "_"
        elif item.isupper():
            final += "_"+item.lower()
        else:
            final += item
    if final[0] == "_":
        final = final[1:]
    return final

>>> to_snake_case("RegularExpressionsAreFunky")
'regular_expressions_are_funky'

>>> to_snake_case("RegularExpressionsAre Funky")
'regular_expressions_are_funky'

>>> to_snake_case("RegularExpressionsAre_Funky")
'regular_expressions_are_funky'

1
+=স্ট্রিংগুলি প্রায়শই একটি খারাপ ধারণা। একটি তালিকাতে যুক্ত করুন এবং ''.join()এটি শেষ পর্যন্ত। বা এই ক্ষেত্রে, কেবল একটি আন্ডারস্কোর দিয়ে এতে যোগদান করুন ...
থিফমাস্টার

21
একক লাইনের নিয়মিত অভিব্যক্তিটি অক্ষম মাল্টি-লাইন অক্ষরের পুনরাবৃত্তি এবং ব্রুট-ফোর্স স্ট্রিং মুংয়ের থেকে প্রায় প্রতিটি ব্যবহারিক পদ্ধতিতে (পঠনযোগ্যতা সহ) সর্বোত্তম নয় কীভাবে ? পাইথন একটি কারণে বাক্সের বাইরে নিয়মিত এক্সপ্রেশন সমর্থন সরবরাহ করে।
সিসিল কারি

1
@ সিসিলকিউরি - নিয়মিত প্রকাশগুলি খুব জটিল। পাইথন যে সংকলক এবং পার্সারটি ব্যবহার করে তা দেখুন: svn.python.org/projects/python/trunk/Lib/sre_compile.py & svn.python.org/projects/python/trunk/Lib/sre_parse.py - সরল স্ট্রিং ম্যানিপুলেশন এটি সম্ভবত আর আর একই কাজ করার চেয়ে অনেক দ্রুত।
ইভান বর্গস্ট্রোম

1
+1 টি। Regexes একটি আসল সিপিইউ সিঙ্ক হতে পারে, এবং নিবিড় গণনাগুলি নাটকীয়ভাবে আপনার অভিনয়গুলি কমিয়ে দেবে lower সাধারণ কাজের জন্য, সর্বদা সাধারণ কার্যকারিতা পছন্দ করুন।
ফ্যাবিয়েন

4
"সাধারণ কাজের জন্য, সর্বদা সাধারণ কার্যকারিতা পছন্দ করুন" অবশ্যই ভাল পরামর্শ, তবে এই উত্তরটি কোনও সাধারণ ফাংশন বা মার্জিত কোনও নয়। রেজেক্স ধীর হতে পারে তবে এই জাতীয় জটিল ক্রিয়াকলাপটিকে ডিফল্ট করা (এটি
ALSO অপরিশোধিত

9

আমি reযদি সম্ভব হয় তবে এড়াতে পছন্দ করি :

def to_camelcase(s):
    return ''.join(['_' + c.lower() if c.isupper() else c for c in s]).lstrip('_')
>>> to_camelcase("ThisStringIsCamelCase")
'this_string_is_camel_case'

1
এটি সর্বাধিক কমপ্যাক্ট যা reলাইব্রেরিটি ব্যবহার করা এবং কেবলমাত্র অন্তর্নির্মিত স্ট্রিমথডস ব্যবহার করে একটি লাইনে স্টাফগুলি করা এড়ানো যায় না! এটি এই উত্তরের অনুরূপ , তবে if ... elseসম্ভাবনাযুক্ত প্রথম অক্ষর হিসাবে "_" যুক্ত করে স্লাইসিং এবং অতিরিক্ত ব্যবহার এড়ানো যায় । আমি এটি সবচেয়ে পছন্দ করি।
কলিডিয়ার

গৃহীত উত্তরের 6.81 µs ± 22.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)জন্য তবে এই প্রতিক্রিয়ার জন্য 2.51 µs ± 25.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)যা 2.5x গুণ দ্রুত! এটা খুবই পছন্দ করি!
WBAR

8
''.join('_'+c.lower() if c.isupper() else c for c in "DeathToCamelCase").strip('_')
re.sub("(.)([A-Z])", r'\1_\2', 'DeathToCamelCase').lower()

7

আমি মনে করি এই সমাধানটি পূর্বের উত্তরের তুলনায় আরও সহজ:

import re

def convert (camel_input):
    words = re.findall(r'[A-Z]?[a-z]+|[A-Z]{2,}(?=[A-Z][a-z]|\d|\W|$)|\d+', camel_input)
    return '_'.join(map(str.lower, words))


# Let's test it
test_strings = [
    'CamelCase',
    'camelCamelCase',
    'Camel2Camel2Case',
    'getHTTPResponseCode',
    'get200HTTPResponseCode',
    'getHTTP200ResponseCode',
    'HTTPResponseCode',
    'ResponseHTTP',
    'ResponseHTTP2',
    'Fun?!awesome',
    'Fun?!Awesome',
    '10CoolDudes',
    '20coolDudes'
]
for test_string in test_strings:
    print(convert(test_string))

কোন ফলাফল:

camel_case
camel_camel_case
camel_2_camel_2_case
get_http_response_code
get_200_http_response_code
get_http_200_response_code
http_response_code
response_http
response_http_2
fun_awesome
fun_awesome
10_cool_dudes
20_cool_dudes

নিয়মিত অভিব্যক্তি তিনটি নিদর্শনগুলির সাথে মেলে:

  1. [A-Z]?[a-z]+: একটানা নিম্ন-অক্ষরের অক্ষর যা optionচ্ছিকভাবে একটি বড়-বড় অক্ষর দিয়ে শুরু হয়।
  2. [A-Z]{2,}(?=[A-Z][a-z]|\d|\W|$): দুই বা ততোধিক পর পরের অক্ষর। এটি ছোট-বড় অক্ষর অনুসরণ করে যদি সর্বশেষের বড় হাতের অক্ষর বাদ দেয় তবে এটি লক হেড ব্যবহার করে।
  3. \d+: ধারাবাহিক সংখ্যা।

ব্যবহার করে re.findallআমরা স্বতন্ত্র "শব্দের" একটি তালিকা পাই যা লোয়ার-কেসে রূপান্তরিত হতে পারে এবং আন্ডারস্কোরগুলির সাথে যোগ দেয়।


1
এখানে স্বতন্ত্রভাবে সংখ্যার টোকেনাইজড পাওয়ার জন্য একটি ভাল উদাহরণ রয়েছে।
গণিত_লা

1
ভাঙা: রূপান্তর করুন ( "AB") -> 'একটি'
adw

5

উভয় .sub () কল ব্যবহার করে কেন আমি ধারণা পাই না? :) আমি রেজেক্স গুরু নই, তবে আমি এইটির সাথে ফাংশনটি সরল করেছিলাম, যা আমার নির্দিষ্ট প্রয়োজনের জন্য উপযুক্ত, আমার কেবলমাত্র উটসেসেড ভার্সগুলিকে পোষ্ট অনুরোধ থেকে ভার্স_উইন্ডসাউন্ডসর রূপান্তর করার জন্য একটি সমাধান প্রয়োজন:

def myFunc(...):
  return re.sub('(.)([A-Z]{1})', r'\1_\2', "iTriedToWriteNicely").lower()

এটি getHTTPResponse এর মতো নামের সাথে কাজ করে না, কারণ শুনেছি এটি নামকরণ খারাপ নাম (এটি getHttpResponse এর মতো হওয়া উচিত, এটি স্পষ্টতই, এই ফর্মটি মুখস্ত করে রাখা সহজ)।


আমি উল্লেখ করতে ভুলে গেছি, যে '{1}' প্রয়োজন হয় না, তবে কখনও কখনও এটি কিছুটা কুয়াশা পরিষ্কার করতে সহায়তা করে।
desper4do

2
-1: এটি ঠিক কাজ করে না। উদাহরণস্বরূপ ব্যবহার করে দেখুন 'HTTPConnectionFactory', আপনার কোড উত্পাদন করে 'h_tt_pconnection_factory', গৃহীত উত্তর থেকে কোড উত্পন্ন হয়'http_connection_factory'
ভের্তেক করুন

4

এখানে আমার সমাধান:

def un_camel(text):
    """ Converts a CamelCase name into an under_score name. 

        >>> un_camel('CamelCase')
        'camel_case'
        >>> un_camel('getHTTPResponseCode')
        'get_http_response_code'
    """
    result = []
    pos = 0
    while pos < len(text):
        if text[pos].isupper():
            if pos-1 > 0 and text[pos-1].islower() or pos-1 > 0 and \
            pos+1 < len(text) and text[pos+1].islower():
                result.append("_%s" % text[pos].lower())
            else:
                result.append(text[pos].lower())
        else:
            result.append(text[pos])
        pos += 1
    return "".join(result)

এটি মন্তব্যে আলোচিত সেই কোণার ক্ষেত্রে সমর্থন করে। উদাহরণস্বরূপ, বলা যায় এর রূপান্তরের করব getHTTPResponseCodeকরার get_http_response_codeমত এটি করা উচিত।


7
-1 কারণ রেজেক্সপ্স ব্যবহারের তুলনায় এটি খুব জটিল।
এরিক হে লেবিগোট

7
EOL, আমি নিশ্চিত যে প্রচুর নন-রেজিপ্সপ লোকেরা অন্যথায় ভাবেন।
ইভান ফসমার্ক 15

এই সমাধানগুলি এই ক্ষেত্রে ব্যর্থ হয়: _Modod, _est_Modod , __est__ মেঠোড, getHTTPrespnsseCode, __get_HTTPresponseCode, _ ক্যামেল_ কেস, _টেষ্ট, এবং _েস্ট_মথোড।
ফ্রিগনু

3
@ ইভান, এই লোকেরা খারাপ প্রোগ্রামার হবে।
জেসি illিলন

3

মজাদার জন্য:

>>> def un_camel(input):
...     output = [input[0].lower()]
...     for c in input[1:]:
...             if c in ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'):
...                     output.append('_')
...                     output.append(c.lower())
...             else:
...                     output.append(c)
...     return str.join('', output)
...
>>> un_camel("camel_case")
'camel_case'
>>> un_camel("CamelCase")
'camel_case'

বা, এর মজাদার জন্য আরও কিছু:

>>> un_camel = lambda i: i[0].lower() + str.join('', ("_" + c.lower() if c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" else c for c in i[1:]))
>>> un_camel("camel_case")
'camel_case'
>>> un_camel("CamelCase")
'camel_case'

3
সিবিআইপিএফ-তে সি-সিপার () পরিবর্তে ... জেড
জিমি

1
পাইথনের রিজেক্সস নেই? একটি দ্রুত 's / [এজেড] \ কে ([এজেড] [এজে]) / _ \ এল $ 1 / জি; পার্লের এলসি $ _ 'কাজটি করে (যদিও এটি getHTTPResponseCode ভালভাবে পরিচালনা করে না; তবে এটি প্রত্যাশিত, এর নাম getHttpResponseCode করা উচিত)
jrockway

5
str.joinযুগে যুগে অবহেলা করা হয়েছে । ''.join(..)পরিবর্তে ব্যবহার করুন।
জন ফুহি

জারকওয়ে: "রে" মডিউলটির মাধ্যমে এটির নিয়মিত এক্সপ্রেশন থাকে। এখানে পোস্ট করা পদ্ধতির চেয়ে রেজেেক্স ব্যবহার করে এই কাজ করা খুব বেশি কঠিন হওয়া উচিত নয়।
ম্যাথু Iselin

পাইথন এখানে নুব, কিন্তু কেন str.join ('', আউটপুট)? শুধু একটি অনুলিপি তৈরি করতে?
টার্কস

3

রেজিক্সগুলি ব্যবহার করা সবচেয়ে কম হতে পারে তবে এই সমাধানটি আরও বেশি পঠনযোগ্য:

def to_snake_case(s):
    snake = "".join(["_"+c.lower() if c.isupper() else c for c in s])
    return snake[1:] if snake.startswith("_") else snake

@ ব্লুয়েড যা সম্পূর্ণরূপে সম্পর্কিত নয়, এই প্রশ্নটির জাঙ্গোর সাথে কোনও সম্পর্ক নেই।
কে-

এটা ঠিক একটি উদাহরণ, HTTPResponseCode, যা পরিচালিত হয় মত stackoverflow.com/a/23561109/15690
নীল রঙের

3

অনেক জটিল পদ্ধতি ... কেবলমাত্র "শিরোনামযুক্ত" গোষ্ঠীটি সন্ধান করুন এবং আন্ডারস্কোর সহ এর লোয়ার কেসড রূপটিতে যোগদান করুন join

>>> import re
>>> def camel_to_snake(string):
...     groups = re.findall('([A-z0-9][a-z]*)', string)
...     return '_'.join([i.lower() for i in groups])
...
>>> camel_to_snake('ABCPingPongByTheWay2KWhereIsOurBorderlands3???')
'a_b_c_ping_pong_by_the_way_2_k_where_is_our_borderlands_3'

আপনি যদি গ্রুপ বা পৃথক গোষ্ঠীর প্রথম চরিত্রের মতো সংখ্যা তৈরি করতে না চান - আপনি ([A-z][a-z0-9]*)মাস্ক ব্যবহার করতে পারেন ।



2

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

def splitSymbol(s):
    si, ci, state = 0, 0, 0 # start_index, current_index 
    '''
        state bits:
        0: no yields
        1: lower yields
        2: lower yields - 1
        4: upper yields
        8: digit yields
        16: other yields
        32 : upper sequence mark
    '''
    for c in s:

        if c.islower():
            if state & 1:
                yield s[si:ci]
                si = ci
            elif state & 2:
                yield s[si:ci - 1]
                si = ci - 1
            state = 4 | 8 | 16
            ci += 1

        elif c.isupper():
            if state & 4:
                yield s[si:ci]
                si = ci
            if state & 32:
                state = 2 | 8 | 16 | 32
            else:
                state = 8 | 16 | 32

            ci += 1

        elif c.isdigit():
            if state & 8:
                yield s[si:ci]
                si = ci
            state = 1 | 4 | 16
            ci += 1

        else:
            if state & 16:
                yield s[si:ci]
            state = 0
            ci += 1  # eat ci
            si = ci   
        print(' : ', c, bin(state))
    if state:
        yield s[si:ci] 


def camelcaseToUnderscore(s):
    return '_'.join(splitSymbol(s)) 

স্প্লিটসিম্বল সকল ক্ষেত্রে প্রকারকে পার্স করতে পারে: উচ্চতর এসকিউএনসিইএন ইন্টারলিভয়েড, আন্ডার_স্কোর, বিজিএসআইএমবিএলএস এবং ক্যামেলসেসড মেথডস

আমি আশা করি এটি কার্যকর হবে


1
ঘৃণ্য, তবে এটি আমার মেশিনে রেগেক্স পদ্ধতির চেয়ে প্রায় 3x দ্রুত চলে। :)
jdiaz5513


1

দুর্দান্ত স্কিম্যাটিকস লাইবটি একবার দেখুন

https://github.com/schematics/schematics

এটি আপনাকে টাইপ করা ডেটা স্ট্রাকচার তৈরি করার অনুমতি দেয় যা অজগর থেকে জাভাস্ক্রিপ্ট স্বাদে সিরিয়ালাইজ / ডিসরিয়ালাইজ করতে পারে, যেমন:

class MapPrice(Model):
    price_before_vat = DecimalType(serialized_name='priceBeforeVat')
    vat_rate = DecimalType(serialized_name='vatRate')
    vat = DecimalType()
    total_price = DecimalType(serialized_name='totalPrice')

1

এই সহজ পদ্ধতিটি কাজটি করা উচিত:

import re

def convert(name):
    return re.sub(r'([A-Z]*)([A-Z][a-z]+)', lambda x: (x.group(1) + '_' if x.group(1) else '') + x.group(2) + '_', name).rstrip('_').lower()
  • আমরা মূলধনীর জন্য সন্ধান করি যা কোনও সংখ্যক (বা শূন্য) বড় অক্ষর দ্বারা পূর্বে থাকে এবং তারপরে কোনও সংখ্যার ছোট হাতের অক্ষর অনুসরণ করে।
  • গোষ্ঠীতে পাওয়া সর্বশেষ মূলধনপত্রের উপস্থিতির ঠিক আগে একটি আন্ডারস্কোর স্থাপন করা হয় এবং অন্য মূলধনপত্রের পূর্বে এটি একটি মূলধন পত্রের আগে স্থাপন করা যেতে পারে।
  • যদি সেখানে চলার আন্ডারস্কোর থাকে তবে সেগুলি সরিয়ে ফেলুন।
  • পরিশেষে, পুরো ফলাফলের স্ট্রিংটি ছোট আকারে পরিবর্তিত হয়।

( এখান থেকে নেওয়া , অনলাইনে কাজের উদাহরণ দেখুন )


এটি বিপরীত প্রশ্নের উত্তর (কীভাবে উটের ক্ষেত্রে রূপান্তর করবেন )।
জাস্টিন

1

বাহ আমি কেবল জাজানো স্নিপেট থেকে এটি চুরি করেছি। রেফ http://djangosnippets.org/snippets/585/

বেশ মার্জিত

camelcase_to_underscore = lambda str: re.sub(r'(?<=[a-z])[A-Z]|[A-Z](?=[^A-Z])', r'_\g<0>', str).lower().strip('_')

উদাহরণ:

camelcase_to_underscore('ThisUser')

রিটার্নস:

'this_user'

রিগেক্স ডেমো


1
স্থানীয় রূপের নাম হিসাবে str ব্যবহার করে খারাপ ফর্ম।
ফ্রিগনু

কোনও স্ট্রিংয়ের শুরু বা শেষের দিকে যদি আন্ডারস্কোর থাকে এবং বড় কোনও অক্ষরের আগে আন্ডারস্কোর থাকে তবে এটি মারাত্মকভাবে ব্যর্থ হয়।
ফ্রিগনু

অ্যাকাউন্ট নম্বরগুলি গ্রহণ করে না
v

কখনও কখনও কোড চুরি করা ভাল ধারণা নয়।
কলিডিয়ার

0

নিয়মিত এক্সপ্রেশন ব্যবহার করে একটি ভয়াবহ উদাহরণ (আপনি সহজেই এটি পরিষ্কার করতে পারেন :)):

def f(s):
    return s.group(1).lower() + "_" + s.group(2).lower()

p = re.compile("([A-Z]+[a-z]+)([A-Z]?)")
print p.sub(f, "CamelCase")
print p.sub(f, "getHTTPResponseCode")

GetHTTPResponseCode এর জন্য কাজ করে যদিও!

বিকল্পভাবে, ল্যাম্বদা ব্যবহার করে:

p = re.compile("([A-Z]+[a-z]+)([A-Z]?)")
print p.sub(lambda x: x.group(1).lower() + "_" + x.group(2).lower(), "CamelCase")
print p.sub(lambda x: x.group(1).lower() + "_" + x.group(2).lower(), "getHTTPResponseCode")

সম্পাদনা: এটিও দেখতে খুব সহজ হওয়া উচিত যে "টেস্ট" এর মতো ক্ষেত্রে উন্নতির সুযোগ রয়েছে কারণ আন্ডারস্কোরটি নিঃশর্তভাবে inোকানো হয়েছে।


0

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

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

অনুসন্ধান করুন:

([a-z]+)([A-Z]|[0-9]+)

প্রতিস্থাপন:

\1_\l\2/

দ্বিতীয় পদক্ষেপ ... উপরের অংশটি নিন এবং সমস্ত ক্যাপগুলি ছোট হাতের মধ্যে রূপান্তর করতে আবার চালান:

অনুসন্ধান করুন:

([A-Z])

প্রতিস্থাপন (এটি ব্যাকস্ল্যাশ, ছোট হাতের এল, ব্যাকস্ল্যাশ, এক):

\l\1

0

আমি একই সমস্যার সমাধান খুঁজছিলাম, আমার চেইনের প্রয়োজন ব্যতীত; যেমন

"CamelCamelCamelCase" -> "Camel-camel-camel-case"

এখানে দুর্দান্ত দ্বি-শব্দ সমাধান থেকে শুরু করে আমি নিম্নলিখিতগুলি নিয়ে এসেছি:

"-".join(x.group(1).lower() if x.group(2) is None else x.group(1) \
         for x in re.finditer("((^.[^A-Z]+)|([A-Z][^A-Z]+))", "stringToSplit"))

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

"-".join(x.group(1).lower() for x in re.finditer("(^[^A-Z]+|[A-Z][^A-Z]+)", "stringToSplit"))

অবশ্যই, আপনি নিয়মিত প্রকাশগুলি প্রাক-সংকলন করতে পারেন বা হাইফেনের পরিবর্তে আন্ডারস্কোরের সাথে যোগ দিতে পারেন, যেমন অন্যান্য সমাধানগুলিতে আলোচনা করা হয়েছে।


0

নিয়মিত অভিব্যক্তি ছাড়াই সংক্ষিপ্ত, তবে HTTPResponseCode => HTptonse_code:

def from_camel(name):
    """
    ThisIsCamelCase ==> this_is_camel_case
    """
    name = name.replace("_", "")
    _cas = lambda _x : [_i.isupper() for _i in _x]
    seq = zip(_cas(name[1:-1]), _cas(name[2:]))
    ss = [_x + 1 for _x, (_i, _j) in enumerate(seq) if (_i, _j) == (False, True)]
    return "".join([ch + "_" if _x in ss else ch for _x, ch in numerate(name.lower())])

0

কোনও গ্রন্থাগার ছাড়া:

def camelify(out):
    return (''.join(["_"+x.lower() if i<len(out)-1 and x.isupper() and out[i+1].islower()
         else x.lower()+"_" if i<len(out)-1 and x.islower() and out[i+1].isupper()
         else x.lower() for i,x in enumerate(list(out))])).lstrip('_').replace('__','_')

কিছুটা ভারী, কিন্তু

CamelCamelCamelCase ->  camel_camel_camel_case
HTTPRequest         ->  http_request
GetHTTPRequest      ->  get_http_request
getHTTPRequest      ->  get_http_request

0

এই সাইটে খুব সুন্দর RegEx প্রস্তাবিত :

(?<!^)(?=[A-Z])

অজগরটির স্ট্রিং স্প্লিট পদ্ধতি থাকলে এটি কাজ করা উচিত ...

জাভাতে:

String s = "loremIpsum";
words = s.split("(?&#60;!^)(?=[A-Z])");

দুর্ভাগ্যক্রমে, পাইথন নিয়মিত এক্সপ্রেশন মডিউলটি (সংস্করণ 3.6 হিসাবে) শূন্য-দৈর্ঘ্যের ম্যাচে বিভাজন সমর্থন করে না।
5:25

0
def convert(name):
    return reduce(
        lambda x, y: x + ('_' if y.isupper() else '') + y, 
        name
    ).lower()

এবং যদি আমাদের ইতিমধ্যে আন-উমেলে ইনপুট দিয়ে একটি মামলা আবশ্যক:

def convert(name):
    return reduce(
        lambda x, y: x + ('_' if y.isupper() and not x.endswith('_') else '') + y, 
        name
    ).lower()

0

কারওর জন্য যদি একটি সম্পূর্ণ উত্স ফাইলটি রূপান্তর করা দরকার তবে এখানে একটি স্ক্রিপ্ট এটি করবে।

# Copy and paste your camel case code in the string below
camelCaseCode ="""
    cv2.Matx33d ComputeZoomMatrix(const cv2.Point2d & zoomCenter, double zoomRatio)
    {
      auto mat = cv2.Matx33d::eye();
      mat(0, 0) = zoomRatio;
      mat(1, 1) = zoomRatio;
      mat(0, 2) = zoomCenter.x * (1. - zoomRatio);
      mat(1, 2) = zoomCenter.y * (1. - zoomRatio);
      return mat;
    }
"""

import re
def snake_case(name):
    s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
    return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()

def lines(str):
    return str.split("\n")

def unlines(lst):
    return "\n".join(lst)

def words(str):
    return str.split(" ")

def unwords(lst):
    return " ".join(lst)

def map_partial(function):
    return lambda values : [  function(v) for v in values]

import functools
def compose(*functions):
    return functools.reduce(lambda f, g: lambda x: f(g(x)), functions, lambda x: x)

snake_case_code = compose(
    unlines ,
    map_partial(unwords),
    map_partial(map_partial(snake_case)),
    map_partial(words),
    lines
)
print(snake_case_code(camelCaseCode))

-1

এই একটার সাথে আমার বেশ শুভকামনা রইল:

import re
def camelcase_to_underscore(s):
    return re.sub(r'(^|[a-z])([A-Z])',
                  lambda m: '_'.join([i.lower() for i in m.groups() if i]),
                  s)

এই স্পষ্টত গতির জন্য অপ্টিমাইজ করা যেতে পারে একটি ছোট বিট যদি আপনি করতে চান।

import re

CC2US_RE = re.compile(r'(^|[a-z])([A-Z])')

def _replace(match):
    return '_'.join([i.lower() for i in match.groups() if i])

def camelcase_to_underscores(s):
    return CC2US_RE.sub(_replace, s)

-1
def convert(camel_str):
    temp_list = []
    for letter in camel_str:
        if letter.islower():
            temp_list.append(letter)
        else:
            temp_list.append('_')
            temp_list.append(letter)
    result = "".join(temp_list)
    return result.lower()

-3

ব্যবহার করুন: str.capitalize() স্ট্রিংয়ের প্রথম অক্ষরকে (ভেরিয়েবল স্ট্রের অন্তর্ভুক্ত) একটি মূল অক্ষরে রূপান্তর করতে এবং পুরো স্ট্রিংটি প্রদান করে।

উদাহরণ: আদেশ: "হ্যালো"। মূলধন () আউটপুট: হ্যালো


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