I have the following string and I would like to extract the elements (xx="yy") and what's between the brackets. Here's an example:
[caption id="get this" align="and this" width="and this" caption="and this"]this too please[/caption]
I've tried the following code but I'm quite a noob with regex.
re.sub(r'\[caption id="(.*)" align="(.*)" width="(.*)" caption="(.*)"\](.*)\[\/caption\]', "tokens: %1 %2 %3 %4 %5", self.content开发者_运维知识库, re.IGNORECASE)
Thanks a lot in advance!
It's probably not working for you because .*
is greedy. Try [^"]*
in its place. [^"]
means the set of all characters except the quote character. Also, as you've pointed out in the comments, the token syntax, is \\n
, not %n
. Try this:
re.sub(r'\[caption id="([^"]*)" align="([^"]*)" width="([^"]*)" caption="([^"]*)"\](.*)\[\/caption\]', "tokens: \\1 \\2 \\3 \\4 \\5", self.content, re.IGNORECASE)
Do the contents of the caption tag span multiple lines? If they do .*
won't capture the newlines. You'll need to us something like [^\x00]*
instead. [^\x00]
means the set of all charchters except the null character.
re.sub(r'\[caption id="([^"]*)" align="([^"]*)" width="([^"]*)" caption="([^"]*)"\]([^\x00]*)\[\/caption\]', "tokens: \\1 \\2 \\3 \\4 \\5", self.content, re.IGNORECASE)
On the off chance that your strings can actually legitimately contain null characters, you would need to use the re.DOTALL
flag instead.
You might be able to leverage the power of Python's standard SGML/HTML/XML parsing modules: if it is safe to substitute "[]" for "<>", then you can do this substitution in order to produce valid XML, and do the parsing with the standard library XML parsing functions:
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()
This correctly print:
Text part: this too please
Values: ['and this', 'and this', 'get this', 'and this']
The advantage of this approach is that (1) it uses a standard module that many people know; (2) it explicitly shows what you want to do; and (3) you can readily extract more information, handle more complicated values (including values that contain double quotes…), etc.
You could try something like this?
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
精彩评论