"Unescaping" обратные косые черты в строке - PullRequest
1 голос
/ 06 марта 2020

TL; DR;

Я хочу преобразовать строку (представляющую регулярное выражение), например "\\.", в "\." чистым и упругим способом (что-то похожее на sed 's/\\\\/\\/g', я не знаю, может ли это сломаться в крайних случаях)
val.decode('string-escape') не вариант, так как я использую python3.

То, что я пробовал до сих пор:

  • варианты val.replace('\\\\', '\\')
  • посмотрел ответы на эти два вопроса, но я не смог заставить их работать в моем случае
    • варианты val.encode().decode('unicode-escape')
  • взглянули на документы для строк но не смог найти решение

Я уверен, что пропустил соответствующую часть, потому что экранирование строки (и удаление) кажется довольно распространенной и основной проблемой c, но я Я еще не нашел решение = /

Полная история:

У меня есть YAML-файл, похожий на

- !Scheme
      barcode: _([ACGTacgt]+)[_.]
      lane: _L(\d\d\d)[_.]
      name: RKI
      read: _R(\d)+[_.]
      sample_name: ^(.+)(?:_.+){5}
      set: _S(\d+)[_.]
      user: _U([a-zA-Z0-9\-]+)[_.]
      validation: .*/(?:[a-zA-Z0-9\-]+_)+(?:[a-zA-Z0-9])+\.fastq.*
...

, который описывает объект "Схема". Ключ 'name' является идентификатором, а остальные описывают регулярные выражения.

Я хочу иметь возможность анализировать объект из этого YAML, поэтому я написал from_yaml метод класса:

scheme = Scheme()
loaded_mapping = loader.construct_mapping(node)  # load yaml-node as dictionary WARNING! loads str escaped

# re.compile all keys except name, adding name as regular string and
# unescaping escaped sequences (like '\') in the process
for key, val in loaded_mapping.items():
    if key == 'name':
        processed_val = val
    else:
        processed_val = re.compile(val)  # backslashes in val are escaped
    scheme.__dict__[key] = processed_val

проблема в том, что loader.construct_mapping(node) загружает строки с экранированными обратными слешами, поэтому регулярное выражение больше не является правильным.

Я пробовал несколько вариантов val.encode().decode('unicode-escape') и val.replace('\\\\', '\\'), но безуспешно с этим

Если у кого-то есть идея, как с этим справиться, я буду очень признателен! Я не женат на этом конкретном c способе ведения дел и открыт для альтернативных подходов.

С уважением!

1 Ответ

1 голос
/ 06 марта 2020

Предполагая, что у меня есть этот супер простой YAML-файл

lane: _L(\d\d\d)[_.]

и я загружаю его с PyYAML следующим образом:

import yaml
import re

with open('test.yaml', 'rb') as stream:
    data = yaml.safe_load(stream)

lane_pattern = data['lane']
print(lane_pattern)

lane_expr = re.compile(data['lane'])
print(lane_expr)

Тогда результат будет именно таким, как и следовало ожидать:

_L(\d\d\d)[_.]
re.compile('_L(\\d\\d\\d)[_.]')

При синтаксическом анализе YAML двойного экранирования строк не происходит, поэтому вам нечего скрывать.

...