Dopasowanie tylko pierwszego wystąpienia w linii z Regex


42

Jestem całkowicie nowy w wyrażeniach regularnych i byłbym bardzo wdzięczny za wszelką pomoc.

Zadanie jest proste. Mam plik CSV z zapisami o następującej treści:

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

Chciałbym zastąpić pierwszy przecinek spacją i pozostawić pozostałe przecinki nietknięte dla każdej linii. Czy istnieje wyrażenie regularne, które będzie pasować tylko do pierwszego przecinka?

Próbowałem to: ^.....,. To pasuje do przecinka, ale pasuje również do całej długości ciągu poprzedzającego przecinek, więc jeśli spróbuję zastąpić to spacją, wszystkie liczby również zostaną usunięte.


jakiego narzędzia używasz? (sed, perl, awk, coś jeszcze?)
Mat.

Textpad (Windows)
cows_eat_hay,

Odpowiedzi:


53

Pasujący wzór może być:

^([^,]+),

To znaczy

^        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

W np. Perl, całe dopasowanie i zamiana wyglądałoby następująco:

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

Część zamienna po prostu bierze wszystko, co pasuje, i zastępuje ją pierwszym zapamiętanym blokiem i dodaje spację. Koma jest „upuszczana”, ponieważ nie należy do pierwszej grupy przechwytywania.


Niesamowite! Dziękuję Mat, zadziałało świetnie. Właściwie to nie działało w Textpadzie (myślę, że ich regex jest ograniczony), więc skończyło się pobieranie PowerGrep, skorzystałem z wyszukiwania i zastąpiłem podanym wyrażeniem i działało świetnie. Dzięki również za miłe wyjaśnienie, pomaga zrozumieć, co się dzieje.
cows_eat_hay

7
s/,/ /

To domyślnie (tzn. Bez gopcji) zastępuje tylko pierwsze dopasowanie.


1
Czy to faktycznie jest składnia wyszukiwania i zamiany Textpada?
Daniel Beck

1
Jest to składnia sed, perli kilka innych narzędzi.
pabouk

3

Ten powinien pasować tylko pierwszy numer i przecinek: ^(\d{5}),. Jeśli chcesz pożreć wszystko inne w linii, zmień wyrażenie regularne na:^(\d{5}),(.*)$


To także załatwiło sprawę. Właściwie skończyło się na rozwiązaniu Mat, ale przetestowałem też twoje i to działa. Dzięki za pomoc!
cows_eat_hay

Dlaczego \d{5}i nie [^,]*? To byłoby co najmniej bardziej ogólne.
JustinCB

2

Bardziej eleganckim rozwiązaniem jest użycie leniwego dopasowywania:

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

które będą grupować znaki, przesuwając od początku ciągu ( ^) do końca o jeden znak ( .+?) na każdym kroku, aż znajdzie pierwszy znak przecinka. Cała ta grupa wraz z pierwszym wystąpieniem przecinka zostanie zastąpiona przez grupę ( \1) i znak spacji.


Zauważ, że to nie pasuje do linii, która nie zawiera przecinka (pojedyncza wartość w linii). Dopasowując każdy * może być lepsze niż jeden +, taks/^(.*?),/\1 /
Jeff Puckett

Możesz także zrobić s/^([^,]*),/\1 /, co pasowałoby do początku, cokolwiek, nie przecinek, potem przecinek. Czy nie wiesz, że s//to nie zmienia niczego, co nie pasuje?
JustinCB

1

TextPad zawsze miał możliwość używania notacji posiksowej, ale musisz zmienić ustawienia w innym oknie dialogowym. Aby użyć domyślnych ustawień TextPada dla wyrażeń regularnych, musisz „uciec” nawiasami otwierającymi i zamykającymi:

Zamień spację po 5-cyfrowym kodzie pocztowym na początku każdego wiersza

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

Z zakładką

\1\t

Jak wyżej ^ oznacza początek linii

\ (jest „nawiasiem ucieczkowym” i oznacza początek pierwszego wyrażenia wyszukiwania, czyli pięciu cyfr

[0–9] + oznacza jedną lub więcej cyfr (nie tylko 5-cyfrowe kody pocztowe)

\) jest kolejnym „nawiasiem ucieczkowym” oznaczającym koniec pierwszego wyrażenia wyszukiwania

[] to tylko spacja (możesz pominąć nawiasy kwadratowe, ale wtedy nikt nie będzie mógł tego zobaczyć na tej stronie :-)

W wyrażeniu zastępczym

\ 1 to pierwsze wyszukiwane wyrażenie, część między nawiasami powyżej (jedna lub więcej cyfr)

\ t jest znakiem tabulacji

Tak więc polecenie wyszukiwania i zamiany szuka jednej lub więcej cyfr, po których następuje spacja. Następnie zastępuje to wszystko tą samą grupą cyfr, po której następuje tabulator.

Nie sądzę, że istnieje sposób, aby po prostu znaleźć „spację występującą po 5 cyfrach”, aby można było po prostu wymienić spację bez dotykania cyfr. Musisz znaleźć 5 cyfr (pierwszy ciąg), a następnie spację (drugi ciąg). Następnie, mimo że wydaje się zbędny lub kłopotliwy, WYMIENIJ oryginalny ciąg 5 cyfr na JEDNEGO, a następnie tabulatora (drugi ciąg).

Każdy, kto to zna, zapomina, że ​​nowicjusze nie mają o tym pojęcia. Dlatego mówię to dla ciebie, przyjacielu.

Ed Poor Math Opiekun i emerytowany programista komputerowy w Nowym Jorku


0

Aby dopasować tylko pierwsze wystąpienie wyrażenia regularnego, usuń wszystkie flagi. Każde wyrażenie regularne zawiera następujące możliwe flagi i zwykle domyślnie używa flagi globalnej, która pasuje do więcej niż jednego wystąpienia:

  • / g = Z tą flagą wyszukiwanie wyszukuje wszystkie dopasowania, bez niego - zwracana jest tylko pierwsza zgodność
  • / i = nie rozróżnia wielkości liter
  • / m = tryb wielu linii
  • / s = wszystkie. aby dopasować znak nowej linii \ n
  • / u = Unicode
  • / y = tryb lepki (wyszukiwanie w określonej lokalizacji)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.