วิธีการเปลี่ยนสตริงทั้งหมดในไฟล์ python จาก snake_case เป็น camelCase ใน sed


5

ฉันลองรูปแบบที่น่าสนใจเช่นนี้จาก commandlinefu

sed -r "s/('[a-z]+)_([a-z])([a-z]+)/\1\U\2\L\3/"

แต่อย่างใดมันไม่ทำงาน มีอยู่สิ่งหนึ่งที่พวกเขาลืมตัวเลขซึ่งฉันสามารถแก้ไขได้ แต่รูปแบบนี้ใช้ได้กับขีดเส้นใต้เดียวเท่านั้น ตัวอย่างเช่นถ้าฉันมีสตริงในไฟล์

'foo_bar_foo'

มันจะแปลงเป็น

'fooBar_foo'

. ซึ่งไม่ใช่สิ่งที่ฉันต้องการ (ฉันต้องการ'fooBarFoo')

ฉันต้องการเปลี่ยนสตริงในไฟล์ไม่ใช่ชื่อตัวแปรหรืออย่างอื่น ตัวอย่างเช่นนี้

delta_limits=Limits(general_settings['signal_lower_limit']

ควรเป็นแบบนี้

delta_limits=Limits(general_settings['signalLowerLimit']

คุณต้องการอะไร 'fooBarFoo'หรือ'FooBarFoo'?
Stéphane Chazelas

@ StéphaneChazelas 'fooBarFoo'
1685095

@ StéphaneChazelasดีไม่ ไม่แน่นอน เพราะฉันไม่ต้องการเปลี่ยนชื่อตัวแปร เฉพาะสตริงในไฟล์ต้นฉบับ
user1685095

โปรดเพิ่มตัวอย่างอินพุตและเอาต์พุตที่คุณต้องการสำหรับตัวอย่างอินพุตนั้นกับคำถามของคุณ
Cyrus

@Cyrus ฉันเพิ่งทำไป
user1685095

คำตอบ:


6

ถ้าผมเข้าใจอย่างถูกต้องคุณต้องการที่จะเปลี่ยน_xไปXตราบใดที่มันเกิดขึ้นภายใน'...'สตริง

จากนั้นด้วย GNU sedคุณสามารถทำได้:

sed -E ":1;s/^(([^']|'[^']*')*'[^']*)_([^'])/\1\u\3/;t1"

นั่นคือแทนที่_Xต่อไปนี้'...ตัวเองดังต่อไปนี้ลำดับของทั้งคำพูดไม่ได้หรือคำพูดที่ตรงกับ

ซึ่งในการป้อนข้อมูลเช่น:

foo_bar 'ab_cd_ef gh_ij' zz_zz 'aa_bb''
delta_limits=Limits(general_settings['signal_lower_limit']

ให้:

foo_bar 'abCdEf ghIj' zz_zz 'aaBb'
delta_limits=Limits(general_settings['signalLowerLimit']

สมมติว่าคุณไม่มีสตริงฝังคำพูดเดียว (เหมือนใน'foo\'bar') หากเป็นเช่นนั้นคุณจะต้องพิจารณาบัญชีสำหรับการ\'หลบหนีด้วย:

sed -E ":1;s/^(([^']|'([^\']|\\\\.)*')*'([^\']|\\\\.)*)_([^'])/\1\u\5/;t1"

(รวมถึงบัญชีด้วย'foo\\')

ที่ยังคงไม่ครอบคลุมถึงคำพูดหรือเส้นทับขวาอย่างต่อเนื่องหรือ"foo'bar" python's '''it's a multi-line quote'''คุณต้องมีเครื่องมือpythonแยกวิเคราะห์เพื่อให้ครอบคลุมทุกกรณี

สำหรับกรณีของคุณโดยเฉพาะ

sed -E ":1;s/('\w*)_(\w)/\1\u\2/g;t1"

อาจเพียงพอ (แทนที่เฉพาะการ_Xติดตาม'\w*) นั่นเป็น GNU sedเทียบเท่า (ยกเว้นสำหรับสิ่งที่\wตรงกับ) ของเกล็นของperlวิธีการ


ดูเหมือนว่าจะทำงานคุณช่วยอธิบายได้ว่ามันทำงานยังไง? ฉันรู้พื้นฐานของ regex ดังนั้นอาจจะไม่เป็นการยากที่จะอธิบาย
user1685095

2

ฉันจะใช้ Perl สำหรับสิ่งนี้:

perl -pe "1 while s/('\w+)_([^']*)/\$1\\u\$2/" <<END
my_variable = 'a_string_with_snake_case_inside'
delta_llimits=Limits(general_settings['signal_lower_limit']
END
my_variable = 'aStringWithSnakeCaseInside'
delta_limits=Limits(general_settings['signalLowerLimit']

ซึ่งหมายความว่า: ในขณะที่การค้นหาและแทนที่ยังคงค้นหาการจับคู่ "1" (ไม่มี op ที่คืนค่าจริง)


ขอบคุณสำหรับคำตอบของคุณ แต่ฉันคิดว่ามันน่าจะเป็นไปได้โดยไม่ต้องมี Perl ฉันสามารถทำได้ใน python หากฉันต้องการหรือ Java หรือภาษาใด ๆ ที่ฉันรู้
user1685095

1
ไม่มีปัญหา. perl เป็นเพียงโปรแกรม (เช่น sed) ที่เกิดขึ้นกับการจัดการข้อความ
เกล็นแจ็

ฉันคิดว่า Perl เป็นภาษาการเขียนโปรแกรม ... ใช่ไหม?
user1685095

ใช่แล้ว. เช่นนั้นแหละ
เกล็นแจ็

โอ้ขอบคุณสำหรับการให้ความกระจ่างแก่ฉัน! ฉันไม่ได้ตระหนักถึงสิ่งนั้น
user1685095
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.