2009-01-14 22 views
8

Tôi đã sau văn bản trong một tập tinVim biểu hiện thường xuyên để loại bỏ tất cả ngoại trừ hai chữ số cuối của số

23456789 

Khi tôi cố gắng thay thế các văn bản trên sử dụng lệnh

1,$s/\(\d\)\(\d\d\d\)\(\d\d\)*\>/\3\g 

Tôi nhận 89 . Không phải là 6789? Bất cứ ai có thể cho tôi biết lý do tại sao nó là 89.

+12

Lưu ý, nếu bạn chuyển đổi \ v, bạn có thể tránh tất cả các dấu gạch chéo ngược đó. 1, $ s/\ v (\ d) (\ d \ d \ d) (\ d \ d) *>/\ 3/g dễ đọc hơn nhiều. –

+1

Bạn đang tìm kiếm một cái gì đó như thế này: 1, $ s/\ v^\ d {4} ((\ d {2}) *)/\ 1/ – AmirW

Trả lời

1

Nhóm 3 được định nghĩa là dài 2 chữ số. Nếu bạn muốn khớp 4 chữ số cuối cùng bạn muốn \(\d\d\d\d\) không có * ở cuối. Nếu bạn chỉ muốn khớp tất cả các chữ số nhưng số 4 đầu tiên, hãy đặt * của bạn vào trong nhóm khớp chứ không phải bên ngoài.

+0

không nên * ở nhóm 3 khớp 2 vừa qua, 4,6 .. chữ số? – chappar

+1

Không, hãy xem các đoạn đường nối trả lời – tddmonkey

4

Khi được viết, regex của bạn chụp một chữ số, sau đó ba chữ số, sau đó bất kỳ số lượng nhóm nào có hai chữ số. Do đó, đối sánh thứ ba sẽ luôn là hai chữ số nếu nó tồn tại. Trong trường hợp thử nghiệm cụ thể của bạn, '89' nằm trong \ 4, không phải \ 3.

Thay đổi regex để

1,$s/\(\d\)\(\d\d\d\)\(\d\d\+\)\>/\3\g 

sẽ cung cấp cho bạn 6789 'như kết quả, vì nó sẽ chụp hai hoặc nhiều chữ số (lên đến bao nhiêu là đang có) trong nhóm thứ ba.

+0

(\ d \ d) * khớp với 2 hoặc nhiều trong số 2. Trong trường hợp của chúng ta, nó phải khớp với 4 chữ số cuối cùng. Vì vậy, không nên \ 3 chứa tất cả 4 chữ số. \ 4 sẽ không có gì vì tôi chỉ có 3(). – chappar

+5

(\ d \ d) * không khớp các chữ số có bội số của 2 (vì vậy 12, 3456, nhưng không phải 789), nhưng nó chỉ * bắt * nguyên tử cuối cùng, vì cùng một dấu ngoặc đơn (cùng nhóm chụp) được sử dụng cho nhiều cặp số. Để đảm bảo bạn chỉ phù hợp với nhiều độ dài, hãy sử dụng regex của Hasturken. – rampion

4

Bạn muốn sử dụng một nhóm phi chụp ở đây, như vậy

1,$s/\(\d\)\(\d\d\d\)\(\%(\d\d\)*\)\>/\3/g 

mang đến cho 6789 như kết quả ở đây, và nếu đầu vào được thay đổi để

2345678 

sẽ có sự thay đổi để 278

+2

Tôi đã thực sự tìm kiếm nhóm không bắt giữ cho regex vim. – lambacck

0

Có thể bạn muốn (cần thêm nhóm gói):

%s/\(\d\)\(\d\d\d\)\(\(\d\d\)*\)\>/\3\g 

Mặc dù tôi không chắc tại sao bạn lại chụp 2 nhóm đầu tiên.

+0

Tại sao tôi cần thêm một bộ dấu ngoặc đơn ở nhóm 3? vấn đề với ví dụ ban đầu của tôi là gì? – chappar

+0

\ (\ d \ d \) * thực sự sẽ khớp với bất kỳ cặp chữ số nào, nhưng nó sẽ không _capture_ chúng để bạn sử dụng sau này. Để nắm bắt nó, bạn cần phải quấn nó trong nhóm riêng của nó - đó là tập hợp thêm các dấu ngoặc đơn. – orip

0

Tôi đã thử cái này trong nvi và nó không hoạt động. Trong vim nó hoạt động, duy nhất mà bạn phải khắc phục các dấu gạch ngang ngược cuối cùng trước khi g, đối với một dấu gạch ngang, như thế này:

1,$s/\(\d\)\(\d\d\d\)\(\d\d\)*\>/\3/g

và nó được thay thế bằng 89. Lý do là bạn đang nói với các * rằng \ d \ d cuối cùng có thể được lặp lại không, một hoặc nhiều lần, và với> bạn đang nói ranh giới từ kết thúc. Với nhóm 3 bạn đang nói rằng bạn muốn nhóm las, nhưng vì * các las hai chữ số (\ d \ d) là 89. Lấy ra *> bạn có thể nhận được 6789. Như thế này:

1,$s/\(\d\)\(\d\d\d\)\(\d\d\)/\3/g

Xem ra vì người đang chơi một phần khó khăn vì với điều này:: 1,$s/\(\d\)\(\d\d\d\)\(\d\d\)\>/\3 bạn nhận được 2389 LOL! Bởi vì từ cuối quan điểm từ-ranh giới dddddd là phù hợp với 456789 và nó được thay thế bằng hai dd cuối cùng, và đó là 89. Vì vậy, bạn nhận được 23 + 89 Tâm thổi!LOL

Các vấn đề liên quan