Solo coincide con la primera aparición en una línea con Regex

42

Soy completamente nuevo en regex y agradecería cualquier ayuda.

La tarea es simple. Tengo un archivo CSV con registros que se leen así:

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

Me gustaría reemplazar la primera coma con un espacio y dejar el resto de las comas intactas, para cada línea. ¿Hay una expresión regular que solo coincida con la primera coma?

He intentado esto: ^.....,. Esto coincide con la coma, sin embargo, también coincide con la longitud completa de la cadena que precede a la coma, por lo que si trato de reemplazar esto con un espacio, todos los números también se eliminan.

cows_eat_hay
fuente
que herramienta estas usando (sed, perl, awk, ¿algo más?)
Mat
Textpad (Windows)
cows_eat_hay

Respuestas:

53

El patrón correspondiente podría ser:

^([^,]+),

Eso significa

^        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

En, por ejemplo, perl, toda la coincidencia y reemplazo se vería así:

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

La parte de reemplazo solo toma todo lo que coincide y lo reemplaza con el primer bloque que recordó y agrega un espacio. El coma se "cae" porque no está en el primer grupo de captura.

Estera
fuente
¡Increíble! Gracias Mat, funcionó muy bien. En realidad, no funcionó en Textpad (creo que su expresión regular es limitada), así que terminé descargando PowerGrep, y usé la búsqueda y reemplazo con la expresión que proporcionó y funcionó muy bien. Gracias también por la buena explicación, ayuda a entender lo que está sucediendo.
cows_eat_hay
7
s/,/ /

Esto, por defecto (es decir, sin la gopción), reemplaza solo la primera coincidencia.

Mork
fuente
1
¿Es esto realmente la sintaxis de búsqueda y reemplazo de Textpad?
Daniel Beck
1
Esta es una sintaxis de sed, perly algunas otras herramientas.
pabouk
3

Esto debe coincidir sólo el primer número y la coma: ^(\d{5}),. Si desea engullir todo lo demás en la línea, cambie la expresión regular a esto:^(\d{5}),(.*)$

alex
fuente
Esto también hizo el truco. En realidad terminé usando la solución de Mat, pero también probé la tuya y funciona. ¡Gracias por la ayuda!
cows_eat_hay 05 de
¿Por qué \d{5}y no [^,]*? Eso sería al menos más genérico.
JustinCB
2

La solución más elegante es usar una combinación perezosa:

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

eso agrupará los caracteres moviéndose desde el inicio de la cadena ( ^) hacia el final por un carácter ( .+?) en cada paso hasta que encuentre el primer signo de coma. Todo este grupo junto con la primera aparición de coma será reemplazado por group ( \1) y espacio de caracteres.

fantasma28147
fuente
Tenga en cuenta que esto no coincidirá con una línea que no contenga una coma (un solo valor en una línea). Coincidir con cualquiera * podría ser mejor que uno, +así ques/^(.*?),/\1 /
Jeff Puckett
También podría hacer s/^([^,]*),/\1 /, que coincidiría con el inicio, cualquier cosa, no una coma, luego una coma. Además, ¿no sabes que eso s//no cambia nada que no coincida?
JustinCB
1

TextPad siempre tuvo la capacidad de utilizar la notación posix, pero debe cambiar la configuración en un cuadro de diálogo diferente. Para usar la configuración predeterminada de TextPad para expresiones regulares, debe "escapar" de los paréntesis de apertura y cierre:

Reemplace el espacio después del código postal de 5 dígitos, al comienzo de cada línea

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

Con pestaña

\1\t

Como arriba, ^ significa inicio de línea

\ (es un "paréntesis escapado" y marca el comienzo de la primera expresión de búsqueda, es decir, los cinco dígitos

[0-9] + significa uno o más dígitos (no solo códigos postales de 5 dígitos)

\) es otro "paréntesis escapado" para marcar el final de la primera expresión de búsqueda

[] es solo un carácter de espacio (puede omitir los corchetes, pero nadie podrá verlo en esta página web :-)

En la expresión de reemplazo

\ 1 es la primera expresión de búsqueda, la parte entre paréntesis anterior (uno o más dígitos)

\ t es un caracter de tabulación

Entonces, el comando buscar y reemplazar busca uno o más dígitos, seguido de un espacio. Luego, reemplaza todo eso con el mismo grupo de dígitos seguido de una pestaña.

No creo que haya una manera sencilla de encontrar "un espacio que viene después de 5 dígitos" para que pueda reemplazar el espacio sin tocar los dígitos. Debes encontrar los 5 dígitos (la primera cadena) seguidos del espacio (la segunda cadena). Luego, aunque parezca redundante o engorroso, REEMPLACE la cadena original de 5 dígitos CON SÍ MISMO, seguida de la pestaña (la segunda cadena).

Todos los que saben esto olvidan que los novatos no tienen idea de esto. Es por eso que te lo estoy explicando, mi amigo.

Ed Poor Tutor de matemáticas y programador informático retirado Ciudad de Nueva York

usuario423655
fuente
0

Para que coincida solo con la primera aparición de cualquier expresión regex, elimine todos los indicadores. Cada expresión regex viene con los siguientes indicadores posibles y, por lo general, usa de manera predeterminada el indicador global que coincidirá con más de una aparición:

  • / g = Con este indicador, la búsqueda busca todas las coincidencias, sin ella, solo se devuelve la primera coincidencia
  • / i = mayúsculas y minúsculas
  • / m = modo multilínea
  • / s = todos. para que coincida con el carácter de nueva línea \ n
  • / u = unicode
  • / y = modo fijo (buscar en una ubicación específica)
Michael Scarpace
fuente