Chỉ khớp với lần xuất hiện đầu tiên trong một dòng với Regex


42

Tôi hoàn toàn mới với regex và tôi sẽ đánh giá rất cao bất kỳ sự giúp đỡ nào.

Nhiệm vụ rất đơn giản. Tôi có một tệp CSV với các bản ghi đọc như thế này:

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

Tôi muốn thay thế dấu phẩy đầu tiên bằng dấu cách và giữ nguyên các dấu phẩy còn lại cho mỗi dòng. Có một biểu thức regex sẽ chỉ khớp với dấu phẩy đầu tiên không?

Tôi đã thử điều này : ^.....,. Điều này khớp với dấu phẩy, tuy nhiên, nó cũng khớp với toàn bộ chiều dài của chuỗi trước dấu phẩy, vì vậy nếu tôi cố gắng thay thế dấu phẩy này bằng một khoảng trắng thì tất cả các số cũng bị xóa.


bạn đang sử dụng công cụ gì? (sed, perl, awk, cái gì khác?)
Mat

Câu trả lời:


53

Mẫu phù hợp có thể là:

^([^,]+),

Điêu đo co nghia la

^        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

Trong ví dụ: perl, toàn bộ trận đấu và thay thế sẽ giống như:

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

Phần thay thế chỉ lấy toàn bộ những thứ khớp và thay thế nó bằng khối đầu tiên bạn nhớ và nối thêm một khoảng trắng. Hôn mê bị "rơi" vì nó không nằm trong nhóm bắt giữ đầu tiên.


Tuyệt vời! Cảm ơn bạn Mat, nó đã làm việc rất tốt. Nó thực sự không hoạt động trong Textpad (tôi nghĩ rằng regex của họ bị hạn chế), vì vậy tôi đã kết thúc việc tải xuống PowerGrep, và sử dụng tìm kiếm và thay thế bằng biểu thức bạn cung cấp và nó hoạt động rất tốt. Cũng cảm ơn vì lời giải thích tốt đẹp, nó giúp hiểu những gì đang xảy ra.
cow_eat_hay

7
s/,/ /

Điều này, theo mặc định (nghĩa là không có gtùy chọn), chỉ thay thế trận đấu đầu tiên.


1
Đây thực sự là cú pháp tìm kiếm & thay thế Textpad?
Daniel Beck

1
Đây là một cú pháp của sed, perlvà một số công cụ khác.
pabouk

3

Điều này chỉ phù hợp với số đầu tiên và dấu phẩy : ^(\d{5}),. Nếu bạn muốn ngấu nghiến mọi thứ khác trong dòng, hãy thay đổi regex thành này:^(\d{5}),(.*)$


Điều này cũng đã làm các mẹo. Tôi thực sự đã kết thúc bằng cách sử dụng giải pháp của Mat nhưng tôi cũng đã thử nghiệm của bạn và nó hoạt động. Cảm ơn đã giúp đỡ!
cow_eat_hay

Tại sao \d{5}& không [^,]*? Điều đó sẽ ít nhất là chung chung hơn.
JustinCB

2

Giải pháp thanh lịch hơn là sử dụng kết hợp lười biếng:

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

sẽ nhóm các ký tự bằng cách di chuyển từ đầu chuỗi ( ^) đến cuối bởi một ký tự ( .+?) trên mỗi bước cho đến khi tìm thấy dấu phẩy đầu tiên. Tất cả nhóm này cùng với dấu phẩy xuất hiện đầu tiên sẽ được thay thế bởi nhóm ( \1) và ký tự khoảng trắng.


Lưu ý rằng điều này sẽ không khớp với một dòng không chứa dấu phẩy (một giá trị duy nhất trên một dòng). Phù hợp với bất kỳ * có thể được tốt hơn so với một +quás/^(.*?),/\1 /
Jeff Puckett

Bạn cũng có thể làm s/^([^,]*),/\1 /, sẽ khớp với bắt đầu, bất cứ điều gì không phải là dấu phẩy, sau đó là dấu phẩy. Ngoài ra, bạn không biết rằng s//nó không thay đổi bất cứ điều gì nó không phù hợp?
JustinCB

1

TextPad luôn có khả năng sử dụng ký hiệu posix, nhưng bạn phải thay đổi cài đặt trong hộp thoại khác. Để sử dụng cài đặt mặc định của TextPad cho các biểu thức thông thường, bạn phải "thoát" các dấu ngoặc đơn mở và đóng:

Thay thế khoảng trắng sau mã zip gồm 5 chữ số, ở đầu mỗi dòng

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

Với tab

\1\t

Như trên, ^ có nghĩa là bắt đầu của dòng

\ (là "dấu ngoặc đơn thoát" và nó đánh dấu sự bắt đầu của biểu thức tìm kiếm đầu tiên, tức là năm chữ số

[0-9] + có nghĩa là một hoặc nhiều chữ số (không chỉ mã zip 5 chữ số)

\) là một "dấu ngoặc đơn thoát" khác để đánh dấu sự kết thúc của biểu thức tìm kiếm đầu tiên

[] chỉ là một ký tự khoảng trắng (bạn có thể bỏ dấu ngoặc, nhưng sau đó không ai có thể nhìn thấy nó trên trang web này :-)

Trong biểu thức thay thế

\ 1 là biểu thức tìm kiếm đầu tiên, phần giữa các dấu ngoặc đơn ở trên (một hoặc nhiều chữ số)

\ t là một ký tự tab

Vì vậy, lệnh tìm kiếm và thay thế tìm kiếm một hoặc nhiều chữ số, theo sau là khoảng trắng. Sau đó, nó thay thế tất cả những thứ đó với cùng một nhóm chữ số theo sau là một tab.

Tôi không nghĩ có cách nào đơn giản là tìm "khoảng trắng xuất hiện sau 5 chữ số" để bạn chỉ có thể thay thế khoảng trắng mà không cần chạm vào chữ số. Bạn phải tìm 5 chữ số (chuỗi đầu tiên) theo sau là khoảng trắng (chuỗi thứ hai). Sau đó, mặc dù có vẻ dư thừa hoặc cồng kềnh, hãy thay thế chuỗi gốc gồm 5 chữ số bằng ITSELF, theo sau là tab (chuỗi thứ hai).

Mọi người biết điều này đều quên rằng người mới không biết gì về điều này. Đó là lý do tại sao tôi đánh vần nó cho bạn, bạn của tôi.

Ed Poor Math Tutor và Lập trình viên Máy tính đã nghỉ hưu Thành phố New York


0

Để chỉ khớp với lần xuất hiện đầu tiên của bất kỳ biểu thức regex nào, hãy xóa tất cả các cờ. Mỗi biểu thức regex đi kèm với các cờ có thể sau đây và thường mặc định sử dụng cờ toàn cầu sẽ khớp với nhiều lần xuất hiện:

  • / g = Với cờ này, tìm kiếm sẽ tìm tất cả các trận đấu mà không có nó - chỉ có trận đấu đầu tiên được trả về
  • / i = trường hợp không nhạy cảm
  • / m = chế độ nhiều dòng
  • / s = tất cả. để khớp với ký tự dòng mới \ n
  • / u = unicode
  • / y = chế độ dính (tìm kiếm ở vị trí cụ thể)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.