У меня есть следующая строка, и я хотел бы извлечь элементы (xx = "yy") и что между скобками. Вот пример:
[caption id = "получить этот" align = "и этот" width = "и этот" caption = "и this"] это тоже, пожалуйста, [/caption]
Я пробовал следующий код, но я довольно noob с регулярным выражением.
re.sub(r'\[caption id="(.*)" align="(.*)" width="(.*)" caption="(.*)"\](.*)\[\/caption\]', "tokens: %1 %2 %3 %4 %5", self.content, re.IGNORECASE)
Заранее большое спасибо!
Вероятно, это не работает для вас, потому что .*
Жадный. Попробуйте [^"]*
на своем месте. [^"]
Означает набор всех символов, кроме символа кавычки. Кроме того, как вы отметили в комментариях, синтаксис токена - \\n
, а не %n
. Попробуй это:
re.sub(r'\[caption id="([^"]*)" align="([^"]*)" width="([^"]*)" caption="([^"]*)"\](.*)\[\/caption\]', "tokens: \\1 \\2 \\3 \\4 \\5", self.content, re.IGNORECASE)
Содержимое тега caption содержит несколько строк? Если они это сделают .*
будет захватывать новые строки. Вам понадобится что-то вроде [^\x00]*
. [^\x00]
означает набор всех charchters, кроме нулевого символа.
re.sub(r'\[caption id="([^"]*)" align="([^"]*)" width="([^"]*)" caption="([^"]*)"\]([^\x00]*)\[\/caption\]', "tokens: \\1 \\2 \\3 \\4 \\5", self.content, re.IGNORECASE)
В случае случайности, что ваши строки могут фактически содержать нулевые символы, вам нужно будет использовать вместо этого флаг re.DOTALL
.
Вы могли бы использовать возможности стандартных синтаксических модулей SGML/HTML/XML Python: если можно заменить "[]" на "<>", вы можете сделать эту подстановку, чтобы создать правильный XML, и сделать синтаксический анализ со стандартными функциями XML-анализа:
import string
from xml.etree import ElementTree as ET
text = '[caption id="get this" align="and this" width="and this" caption="and this"]this too please[/caption]'
xml_text = string.translate(text, string.maketrans('[]', '<>')) # Conversion to XML
parsed_text = ET.fromstring(xml_text) # Parsing
# Extracted information
print "Text part:", parsed_text.text
print "Values:", parsed_text.attrib.values()
Это правильно напечатает:
Text part: this too please
Values: ['and this', 'and this', 'get this', 'and this']
Преимущество такого подхода состоит в том, что (1) он использует стандартный модуль, который многие знают; (2) он явно показывает, что вы хотите сделать; и (3) вы можете легко извлечь дополнительную информацию, обрабатывать более сложные значения (включая значения, содержащие двойные кавычки...) и т.д.
Вы могли бы попробовать что-то вроде этого?
re = '[caption id="get this" align="and this" width="and this" caption="and this"]this too please[/caption]'
re.gsub(/([a-z]*)=\"(.*?)\"/i) do |m|
puts "#{$1} = #{$2}
end