จับคู่เฉพาะสิ่งที่เกิดขึ้นครั้งแรกในบรรทัดกับ Regex


42

ฉันใหม่ทั้งหมดสำหรับ regex และฉันขอขอบคุณความช่วยเหลืออย่างมาก

งานง่าย ฉันมีไฟล์ CSV ที่มีบันทึกที่อ่านดังนี้:

12345,67890,12345,67890
12345,67890,12345,67890
12345,67890,12345,67890
12345,67890,12345,67890
12345,67890,12345,67890

ฉันต้องการแทนที่เครื่องหมายจุลภาคแรกด้วยช่องว่างและเว้นเครื่องหมายจุลภาคที่เหลือให้เหลืออยู่สำหรับทุกบรรทัด มีการแสดงออก regex ที่จะตรงกับเครื่องหมายจุลภาคแรกเท่านั้น?

ฉันลองสิ่งนี้: ^.....,. สิ่งนี้ตรงกับเครื่องหมายจุลภาค แต่ก็ตรงกับความยาวทั้งหมดของสตริงก่อนหน้าเครื่องหมายจุลภาคดังนั้นหากฉันพยายามแทนที่ด้วยช่องว่างตัวเลขทั้งหมดจะถูกลบเช่นกัน


คุณใช้เครื่องมืออะไร (sed, perl, awk มีอย่างอื่นอีกไหม)
Mat

Textpad (Windows)
cows_eat_hay

คำตอบ:


53

รูปแบบการจับคู่อาจเป็น:

^([^,]+),

นั่นหมายความว่า

^        starts with
[^,]     anything but a comma
+        repeated one or more times (use * (means zero or more) if the first field can be empty)
([^,]+)  remember that part
,        followed by a comma

ในเช่น perl การแข่งขันและแทนที่ทั้งหมดจะมีลักษณะดังนี้:

s/^([^,]+),/\1 /

ชิ้นส่วนทดแทนจะนำทุกสิ่งที่จับคู่และแทนที่ด้วยบล็อกแรกที่คุณจำได้และต่อท้ายช่องว่าง อาการโคม่าคือ "ลดลง" เนื่องจากไม่อยู่ในกลุ่มการดักจับแรก


! น่ากลัว ขอบคุณ Mat มันใช้งานได้ดีมาก อันที่จริงมันไม่ทำงานใน Textpad (ฉันคิดว่า regex ของพวกเขามี จำกัด ) ดังนั้นฉันจึงสิ้นสุดการดาวน์โหลด PowerGrep และใช้การค้นหาและแทนที่ด้วยนิพจน์ที่คุณระบุและใช้งานได้ดี ขอบคุณสำหรับคำอธิบายที่ดีช่วยให้เข้าใจว่าเกิดอะไรขึ้น
cows_eat_hay

7
s/,/ /

โดยค่าเริ่มต้นนี้ (เช่นไม่มีgตัวเลือก) แทนที่เฉพาะนัดแรก


1
นี่คือการค้นหา Textpad & แทนที่ไวยากรณ์จริงหรือ
Daniel Beck

1
นี่คือไวยากรณ์ของsed, perlและบางส่วนเครื่องมืออื่น ๆ
pabouk

3

^(\d{5}),นี้ควรตรงกับเพียงหมายเลขแรกและจุลภาค: หากคุณต้องการฮุบทุกอย่างในสายให้เปลี่ยน regex เป็น:^(\d{5}),(.*)$


นี่ก็เป็นกลอุบาย ฉันลงเอยด้วยการใช้สารละลายของ Mat แต่ฉันได้ทำการทดสอบของคุณด้วย ขอบคุณสำหรับความช่วยเหลือ!
cows_eat_hay

ทำไม\d{5}และไม่[^,]*? นั่นจะเป็นเรื่องที่ธรรมดาที่สุด
JustinCB

2

โซลูชันที่หรูหรากว่านี้คือใช้การจับคู่ขี้เกียจ:

s/^(.+?),/\1 /

ที่จะจัดกลุ่มตัวละครโดยการย้ายจากจุดเริ่มต้นของสตริง ( ^) ไปยังจุดสิ้นสุดโดยหนึ่งตัวอักษร ( .+?) ในแต่ละขั้นตอนจนกว่ามันจะพบเครื่องหมายจุลภาคแรก กลุ่มนี้ทั้งหมดพร้อมกับเครื่องหมายจุลภาคแรกจะถูกแทนที่ด้วยกลุ่ม ( \1) และอักขระเว้นวรรค


โปรดทราบว่าสิ่งนี้จะไม่ตรงกับบรรทัดที่ไม่มีเครื่องหมายจุลภาค (ค่าเดียวบนบรรทัด) จับคู่ใด ๆ* อาจจะดีกว่าหนึ่ง+ดังนั้นs/^(.*?),/\1 /
เจฟฟ์ Puckett

คุณสามารถทำได้เช่นs/^([^,]*),/\1 /กันซึ่งจะตรงกับจุดเริ่มต้นไม่มีอะไรที่ไม่ใช่เครื่องหมายจุลภาค นอกจากนี้คุณไม่ทราบว่าs//จะไม่เปลี่ยนแปลงอะไรที่มันไม่ตรงหรือไม่
JustinCB

1

TextPad มีความสามารถในการใช้เครื่องหมาย posix เสมอ แต่คุณต้องเปลี่ยนการตั้งค่าในกล่องโต้ตอบที่แตกต่างกัน ในการใช้การตั้งค่าเริ่มต้นของ TextPad สำหรับการแสดงออกปกติคุณต้อง "หลบหนี" วงเล็บเปิดและปิด:

แทนที่ช่องว่างหลังจากรหัสไปรษณีย์ 5 หลักที่จุดเริ่มต้นของแต่ละบรรทัด

^\([0-9]+\)[ ]

ด้วยแท็บ

\1\t

ดังกล่าวข้างต้น ^ หมายถึงจุดเริ่มต้นของบรรทัด

\ (เป็น "เครื่องหมายวงเล็บที่ใช้ Escape" และเป็นเครื่องหมายจุดเริ่มต้นของนิพจน์การค้นหาแรกนั่นคือตัวเลขห้าหลัก

[0-9] + หมายถึงหนึ่งหลักหรือมากกว่า (ไม่ใช่แค่รหัสไปรษณีย์ 5 หลัก)

\) เป็นอีกหนึ่ง "วงเล็บหนี" เพื่อทำเครื่องหมายจุดสิ้นสุดของนิพจน์การค้นหาแรก

[] เป็นเพียงอักขระเว้นวรรค (คุณสามารถเว้นวงเล็บไว้ได้ แต่ก็ไม่มีใครสามารถดูได้ในหน้าเว็บนี้ :-)

ในการแสดงออกแทน

\ 1 คือนิพจน์การค้นหาแรกส่วนระหว่างวงเล็บด้านบน (หนึ่งหลักหรือมากกว่า)

\ t เป็นอักขระแท็บ

ดังนั้นคำสั่งค้นหาและแทนที่จะค้นหาตัวเลขหนึ่งหลักขึ้นไปตามด้วยช่องว่าง จากนั้นจะแทนที่ทั้งหมดด้วยกลุ่มตัวเลขเดียวกันตามด้วยแท็บ

ฉันไม่คิดว่าจะมีวิธีใดที่จะหา "ช่องว่างที่มาหลังตัวเลข 5 หลัก" ดังนั้นคุณสามารถแทนที่ช่องว่างโดยไม่ต้องสัมผัสตัวเลข คุณต้องค้นหา 5 หลัก (สายแรก) ตามด้วยช่องว่าง (สายที่สอง) จากนั้นแม้ว่าจะดูเหมือนว่าซ้ำซ้อนหรือยุ่งยาก แต่แทนที่สตริงเดิมด้วยตัวเลข 5 หลักด้วย ITSELF ตามด้วยแท็บ (สตริงที่สอง)

ทุกคนที่รู้เรื่องนี้ลืมว่ามือใหม่ไม่มีความรู้เกี่ยวกับเรื่องนี้ นั่นเป็นเหตุผลที่ฉันสะกดคำเพื่อคุณเพื่อนของฉัน

Ed Poor Math Tutor และโปรแกรมเมอร์คอมพิวเตอร์เกษียณอายุ New York City


0

เพื่อให้ตรงกับการเกิดขึ้นครั้งแรกของการแสดงออก regex ใด ๆ ลบธงทั้งหมด นิพจน์ regex แต่ละอันมาพร้อมกับค่าสถานะที่เป็นไปได้ต่อไปนี้และโดยทั่วไปแล้วจะใช้ค่าเริ่มต้นในการใช้ค่าสถานะส่วนกลางซึ่งจะจับคู่มากกว่าหนึ่งเกิดขึ้น:

  • / g = ด้วยการตั้งค่าสถานะนี้การค้นหาจะค้นหาการจับคู่ทั้งหมดโดยไม่มีการจับคู่ - จะส่งคืนการจับคู่ครั้งแรกเท่านั้น
  • / i = ตัวพิมพ์เล็กและใหญ่
  • / m = โหมดหลายบรรทัด
  • / s = ทั้งหมด เพื่อจับคู่อักขระขึ้นบรรทัดใหม่ \ n
  • / u = unicode
  • / y = โหมด sticky (ค้นหาในตำแหน่งที่ระบุ)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.