tag regular all regex regex-negation

regular - Regex: patrón de coincidencia siempre y cuando no esté en el principio



regular expression find tag (6)

Supongamos las siguientes cadenas:

aaa bbb ccc bbb aaa ccc

Quiero hacer coincidir aaa siempre que no esté al principio de la cadena. Estoy tratando de negarlo haciendo algo como esto:

[^^]aaa

Pero no creo que esto sea correcto. Utilizando preg_replace .


Desde que vine aquí a través de la búsqueda de Google, y me interesó una solución que no esté usando ningún aspecto , aquí están mis 2 centavos.

El patrón [^^]aaa coincide con un carácter distinto de ^ y luego 3 a s en cualquier lugar dentro de una cadena. La [^...] es una clase de carácter negado donde ^ no se considera un carácter especial. Tenga en cuenta que el primer ^ que está justo después de [ es especial, ya que denota una negación, y el segundo es solo un símbolo de intercalación literal.

Por lo tanto, un ^ no puede estar dentro [...] para indicar el comienzo de la cadena.

Una solución es utilizar cualquier look negativo, estos dos funcionarán igualmente bien:

(?<!^)aaa

y un lookahead:

(?!^)aaa

¿Por qué también funciona lookahead? Lookarounds son aserciones de ancho cero, y los anclajes también tienen ancho cero, no consumen texto. Literalmente hablando, (?<!^) Verifica si no hay un inicio de la posición de la cadena inmediatamente a la izquierda de la ubicación actual, y (?!^) Verifica si no hay un inicio de la posición de la cadena inmediatamente a la derecha de la ubicación actual . Se están comprobando los mismos lugares , por eso ambos funcionan bien.


Esta situación es la primera vez que veo que las soluciones superan a /K Interesante.

Normalmente los grupos de captura y miradas cuestan pasos adicionales. Pero debido a la naturaleza de esta tarea, el motor de expresiones regulares puede navegar la cadena más rápido en la búsqueda de la aaa luego mirar hacia atrás para comenzar el anclaje de la cadena.

Añadiré un par de patrones /K para la comparación.

Estoy usando el modificador de patrón s en caso de que el carácter principal sea un carácter de nueva línea (que normalmente no coincidiría). Simplemente pensé que agregaría esta consideración para abordar de manera preventiva un caso marginal que pueda plantearme.

Nuevamente, este es un escenario esclarecedor porque en todos los demás casos de expresiones regulares que he tratado con /K supera a las otras técnicas.

Matriz de comparación de pasos:

| `~./Kaaa~s` | `~.+?/Kaaa~s` | `(?<!^)aaa` | `(?!^)aaa` | `.(aaa)` | --------------|-------------|---------------|-------------|------------|----------| `aaa bbb ccc` | 12 steps | 67 steps | 8 steps | 8 steps | 16 steps | --------------|-------------|---------------|-------------|------------|----------| `bbb aaa ccc` | 15 steps | 12 steps | 6 steps | 6 steps | 12 steps |

Lo que se lleva es: para conocer la eficiencia de sus patrones, escúpalos en regex101.com y compare los conteos de pasos.

Además, si sabe exactamente qué subcadena está buscando y no necesita un patrón de strpos() regulares, entonces debería usar strpos() como una buena práctica (y solo verifique que el valor devuelto sea > 0 ).



Puedes mirar hacia atrás para asegurarte de que no está al principio. (?<!^)aaa


Si no desea utilizar lookbehind, use esta expresión regular:

/.(aaa)/

Y usa el matched group # 1 .


Vine aquí buscando una solución para el motor re2, utilizada por las hojas de cálculo de Google, que no admite búsquedas. Pero las respuestas aquí me dieron la idea de usar lo siguiente. No entiendo por qué tengo que reemplazar por el grupo capturado, pero de todos modos, funciona.

aaa bbb ccc
bbb aaa ccc

([^^])aaa

sustituir por:

$1zzz

reuslts en:

aaa bbb ccc
bbb zzz ccc