Regex ile aynı çizgide yalnızca ilk oluşumun eşleştirilmesi


42

Regex için tamamen yeni ve her türlü yardımı çok takdir ediyorum.

Görev basit. Bu gibi okuma kayıtları olan bir CSV dosyası var:

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

Her virgül için ilk virgül ile bir boşluk bırakıp virgülün kalanını bozulmadan bırakmak istiyorum. Yalnızca ilk virgülle eşleşen bir regex ifadesi var mı?

Bu çalıştı: ^.....,. Bu, virgülle eşleşir, ancak, virgülden önceki dizginin tüm uzunluğu ile de eşleşir, bu nedenle bunu bir boşlukla değiştirmeye çalışırsam, tüm sayılar da silinir.


hangi aracı kullanıyorsun (sed, perl, awk, başka bir şey?)
Mat

Yanıtlar:


53

Eşleşen model şöyle olabilir:

^([^,]+),

Bunun anlamı

^        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

Örneğin perl'de tüm eşleşme ve değiştirme şöyle görünür:

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

Yedek parça sadece eşleşen her şeyi alır ve onu hatırladığınız ve bir boşluk ekleyen ilk blok ile değiştirir. Koma "düşmüş" çünkü ilk ele geçirme grubunda değil.


Müthiş! Teşekkürler Mat, harika çalıştı. Aslında Textpad'de çalışmadı (regex'in sınırlı olduğunu düşünüyorum), bu yüzden PowerGrep'i indirmeyi bıraktım ve aradığınız ifadeyi kullandığınız ifadeyle değiştirdim ve harika çalıştı. Güzel açıklama için ayrıca teşekkürler, neler olduğunu anlamanıza yardımcı olur.
cows_eat_hay

7
s/,/ /

Bu, varsayılan olarak (yani gseçenek olmadan ) yalnızca ilk eşleşmenin yerini alır.


1
Bu gerçekte Textpad'de arama ve sözdizimi yerine mi kullanılıyor?
Daniel Beck

1
Bu bir sözdizimi sed, perlve diğer bazı araçları.
pabouk

3

Bu sadece ilk sayı ve virgül eşleşmesi gerekir: ^(\d{5}),. Satırdaki diğer her şeyi yükseltmek istiyorsanız, regex'i şu şekilde değiştirin:^(\d{5}),(.*)$


Bu aynı zamanda hile yaptı. Aslında Mat'ın çözümünü kullandım ama seninkini de test ettim ve işe yarıyor. Yardım için teşekkürler!
cows_eat_hay

Neden \d{5}ve değil [^,]*? Bu @ en azından daha genel olurdu.
JustinCB

2

Daha zarif bir çözüm tembel eşleme kullanmaktır:

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

karakterleri ilk virgül işareti bulana kadar ( ) basamağından ^sonuna kadar her karakterde bir karakter ( .+?) yaparak karakterleri gruplandırır . Tüm bu grup, ilk virgül oluşumuyla birlikte grup ( \1) ve boşluk karakteriyle değiştirilecektir.


Bunun, virgül içermeyen bir satırla eşleşmeyeceğini unutmayın (satırdaki tek bir değer). Herhangi Eşleştirme * olabilir daha iyi biri olmak +öylesines/^(.*?),/\1 /
Jeff Puckett

Ayrıca s/^([^,]*),/\1 /, başlangıç ​​ile eşleşen, virgül olmayan her şeyi virgülle de yapabilirsiniz. Ayrıca, s//uyuşmadığı hiçbir şeyi değiştirmeyeceğini bilmiyor musunuz ?
JustinCB

1

TextPad her zaman posix gösterimini kullanma yeteneğine sahipti, ancak ayarları farklı bir iletişim kutusunda değiştirmeniz gerekiyor. TextPad'in normal ifadelerinde varsayılan ayarları kullanmak için, açma ve kapama parantezlerini "terk etmelisiniz":

Her satırın başında, 5 basamaklı posta kodundan sonra boşluğu değiştirin

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

Sekmesi ile

\1\t

Yukarıdaki gibi, ^ satırın başlangıcı anlamına gelir

\ ("kaçak parantez" dir) ve ilk arama ifadesinin başlangıcını, yani beş basamağı işaretler

[0-9] +, bir veya daha fazla rakam (yalnızca 5 basamaklı posta kodları değil) anlamına gelir

\) ilk arama ifadesinin sonunu işaretleyen başka bir "kaçan parantez" dir

[] sadece bir boşluk karakteridir (parantezleri dışarıda bırakabilirsiniz, ancak daha sonra kimse bu web sayfasında göremezdi :-)

Değiştirme ifadesinde

\ 1, ilk arama ifadesidir, yukarıdaki parantezler arasındaki kısımdır (bir veya daha fazla rakam)

\ t bir sekme karakteridir

Bu nedenle, arama ve değiştirme komutu bir veya daha fazla rakam ve ardından boşluk arar. Ardından, hepsini sekme izleyen aynı basamak grubuyla değiştirir.

"5 basamaktan sonra gelen bir boşluk" bulmanın basit bir yolu olduğunu sanmıyorum, bu yüzden boşlukları basamaklara dokunmadan değiştirebilirsiniz. 5 haneyi (ilk dize), ardından boşluğu (ikinci dize) bulmanız gerekir . Sonra, gereksiz veya hantal görünmesine rağmen, 5 basamaktan oluşan orijinal diziyi ITSELF ile, ardından sekmeyle (ikinci dizge) DEĞİŞTİR.

Bunu bilen herkes yenilerin bu konuda hiçbir fikrinin olmadığını unutuyor. Bu yüzden senin için heceliyorum arkadaşım.

Ed Zavallı Matematik Öğretmeni ve emekli Bilgisayar Programcısı New York City


0

Herhangi bir regex ifadesinin yalnızca ilk oluşumunu eşleştirmek için tüm bayrakları kaldırın. Her bir regex ifadesi, aşağıdaki olası bayraklarla birlikte gelir ve genellikle birden fazla oluşumla eşleşecek olan genel bayrağın kullanılmasına varsayılan olarak ayarlanır:

  • / g = Bu bayrakla arama, onsuz tüm eşleşmeleri arar - yalnızca ilk eşleşme döndürülür
  • / i = büyük / küçük harf duyarlı
  • / m = çoklu hat modu
  • / s = tümü. yeni satır karakteriyle eşleşmek için \ n
  • / u = unicode
  • / y = yapışkan mod (belirli bir yerde arama)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.