Estoy tratando de hacer coincidir las barras diagonales dobles en una cadena, pero solo cuando hay 2 y no 3, así puedo cambiar el 2 por 3.

Sé que \\{2} coincidirá con una barra diagonal doble, excepto que también coincidirá con las 2 primeras barras cuando haya 3 presentes.

Por ejemplo en la cadena

{"files":{"windows": {"%windir%\\\System32\\drivers\\etc\\lmhosts.sam":{"ignore":{"id":32}},"%windir%\\System32\\\drivers\\etc":{"ignore":{"id":32}},"%windir%\\System32\\drivers\\etc\\hosts":{"ignore":{"id":32}}}}}

Hay múltiples barras dobles que deseo igualar y reemplazar, pero también hay algunas barras triples que deseo dejar solo.

Entonces, mi pregunta, ¿cómo hacer coincidir la barra doble cuando no se sienta junto a otra barra?

Heres un enlace Regex101 para jugar con. https://regex101.com/r/kWIscW/1

Además, haciendo esto en Ruby.

2
Cheyne 29 dic. 2016 a las 03:28

3 respuestas

La mejor respuesta

Primero abordemos las barras invertidas en literales de cadena,

  • "\\" es una barra invertida
  • "\\\\" son dos barras invertidas
  • "\\\\\\" son tres barras invertidas

¿Por qué? La barra diagonal inversa es la secuencia de escape en literales de cadena, por ejemplo, "\n" es un salto de línea y, por lo tanto, una barra diagonal inversa debe escaparse con una barra diagonal inversa para codificar una barra diagonal inversa.

Ahora intenta esto

string = "\\\\aaa\\\\bbb\\\\\\ccc"
string.gsub(/\\+/) { |match| match.size == 2 ? '/' : match  } 
# => "/aaa/bbb\\\\\\ccc"

¿Como funciona esto?

  • /\\+/ coincide con cualquier secuencia de barras invertidas
  • match.size == 2 filtra los que tienen longitud 2
  • Y luego simplemente reemplazamos esos
2
akuhn 29 dic. 2016 a las 01:14

¿Qué tal:

\b\\{2}\b

Para definir que \\ eres el único personaje evaluado

Otra posibilidad es mirar hacia atrás y mirar hacia adelante, sin embargo, no estoy seguro de que su motor regex lo admita:

(?<=[^\\])\\{2}(?=[^\\])
3
Dalorzo 29 dic. 2016 a las 00:42
r = /
    (?<!\\)  # do not match a backslash, negative lookbehind
    \\\\     # match two backslashes
    (?!\\)   # do not match a backslash, negative lookahead
    /x       # free-spacing regex definition mode

str = "\\\\\ are two backslashes and here are three \\\\\\ of 'em"
puts str  
  # \\ are two backslashes and here are three \\\ of 'em
str.scan(r)
  #=> ["\\\\"] 

Tenga en cuenta que s = "\\\\\ " son dos barras invertidas seguidas de un espacio escapado.

s.size
  #=> 3
s[0].ord
  #=> 92
92.chr
  #=> "\\"
s[1].ord
  #=> 92 
s[2].ord
  #=> 32 
2
Cary Swoveland 29 dic. 2016 a las 01:30