2009-01-14 15 views
8

He siguientes de texto en un archivoVim expresión regular para eliminar todos menos los dos últimos dígitos del número de

23456789 

Cuando traté de reemplazar el texto anterior con el comando

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

estoy recibiendo 89 . ¿No debería ser 6789? ¿Alguien puede decirme por qué es 89?

+12

Tenga en cuenta que si usa el modificador \ v, puede evitar todos los pares pareados invertidos. 1, $ s/\ v (\ d) (\ d \ d \ d) (\ d \ d) *>/\ 3/g es mucho más fácil de leer. –

+1

¿Está buscando algo como esto: 1, $ s/\ v^\ d {4} ((\ d {2}) *)/\ 1/ – AmirW

Respuesta

1

El grupo 3 se define como de 2 dígitos de longitud. Si desea hacer coincidir los últimos 4 dígitos, quiere \(\d\d\d\d\) sin * al final. Si solo desea hacer coincidir todos los dígitos, pero los primeros 4, coloque su * dentro del grupo en lugar de afuera.

+0

no debe * en el partido del grupo 3 el último 2, 4,6 .. dígitos? – chappar

+1

No, ver las respuestas de las rampas – tddmonkey

4

Como está escrito, su expresión regular captura un dígito, luego tres dígitos, luego cualquier cantidad de grupos de dos dígitos cada uno. El tercer partido, por lo tanto, siempre será de dos dígitos si existe. En su caso de prueba particular, el '89' está en \ 4, no \ 3.

Cambio de la expresión regular para

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

te dará '6789' como el resultado, ya que capturará dos o más dígitos (hasta tantos como hay) en el tercer grupo.

+0

(\ d \ d) * coincide con 2 o múltiples de 2. En nuestro caso, debe coincidir con los últimos 4 dígitos. Entonces, no debería \ 3 contener los 4 dígitos. \ 4 no tendrá nada ya que solo tengo 3(). – chappar

+5

(\ d \ d) * hace coincidir dígitos de múltiplos de longitud de 2 (por lo que 12, 3456, pero no 789), pero solo * captura * el último átomo, ya que se utilizan los mismos paréntesis (el mismo grupo de captura) múltiples pares de números. Para asegurarte de que solo estás haciendo coincidir incluso varias longitudes, usa la expresión regular de Hasturken. – rampion

4

que desea utilizar un grupo no capturar aquí, al igual que

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

que da 6789 como el resultado aquí, y si la entrada fue cambiado a

2345678 

cambiaría la línea de 278

+2

En realidad estaba buscando el grupo sin captura para vim regex. – lambacck

0

Probablemente desee (necesita un grupo de envoltura adicional):

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

Aunque no estoy seguro de por qué está capturando los primeros 2 grupos.

+0

¿Por qué necesito un conjunto adicional de paréntesis en el grupo 3? ¿Cuál fue el problema con mi ejemplo original? – chappar

+0

\ (\ d \ d \) * de hecho coincidiría con cualquier par de dígitos, pero no los capturará para su uso posterior. Para capturarlo, debe envolverlo en su propio grupo; ese es el conjunto extra de paréntesis. – orip

0

He intentado esto en nvi y no funciona. En vim funciona, solo que debe corregir el tablero invertida final antes de la g, por un guión, como esto:

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

y se reemplaza con 89. La razón es que usted está diciendo con el * que el último \ d \ d puede repetirse cero, una o más veces, y con> está diciendo límite de palabra final. Con el grupo 3 que dice que desea que el grupo de las, pero debido a las * Las los dos dígitos (\ d \ d) son 89. Sacar la *> usted puede conseguir 6789. De esta manera:

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

Cuidado con los> que está jugando una parte difícil, porque con esto:: 1,$s/\(\d\)\(\d\d\d\)\(\d\d\)\>/\3 que presentamos lo mejor 2389 LOL! Porque desde el final de la perspectiva del límite de palabras, dddddd coincide con 456789 y se reemplaza con los dos últimos dd, y eso es 89. Entonces obtienes 23 + 89 ¡Alucinante!LOL

Cuestiones relacionadas