2

我想解析这个 CSS 选择器(以及其他类似形式的): div.class1#myid.class2[key=value]

并让它匹配“.class1”和“.class2”,但我不知道要使用什么正则表达式..

示例:http ://www.rubular.com/r/3dxpzyJLeK

在理想的世界中,我还想提取:

  • 类型(即 div)
  • 类(即类列表)
  • id(即 myid)
  • 钥匙(即钥匙)
  • 运算符(即 =)
  • 价值(即价值)

但我无法掌握基础知识!

任何帮助将不胜感激:)

谢谢!

4

3 回答 3

2

非常感谢大家的建议和帮助。我将它们绑定到以下两个正则表达式模式中:

这个解析 CSS 选择器字符串(例如 div#myid.myclass[attr=1,fred=3]) http://www.rubular.com/r/2L0N5iWPEJ

cssSelector = re.compile(r'^(?P<type>[\*|\w|\-]+)?(?P<id>#[\w|\-]+)?(?P<classes>\.[\w|\-|\.]+)*(?P<data>\[.+\])*$')

>>> cssSelector.match("table#john.test.test2[hello]").groups()
('table', '#john', '.test.test2', '[hello]')
>>> cssSelector.match("table").groups()
('table', None, None, None)
>>> cssSelector.match("table#john").groups()
('table', '#john', None, None)
>>> cssSelector.match("table.test.test2[hello]").groups()
('table', None, '.test.test2', '[hello]')
>>> cssSelector.match("table#john.test.test2").groups()
('table', '#john', '.test.test2', None)
>>> cssSelector.match("*#john.test.test2[hello]").groups()
('*', '#john', '.test.test2', '[hello]')
>>> cssSelector.match("*").groups()
('*', None, None, None)

而这个属性(例如 [link,key~=value])http://www.rubular.com/r/2L0N5iWPEJ

attribSelector = re.compile(r'(?P<word>\w+)\s*(?P<operator>[^\w\,]{0,2})\s*(?P<value>\w+)?\s*[\,|\]]')

>>> a = attribSelector.findall("[link, ds9 != test, bsdfsdf]")
>>> for x in a: print x
('link', '', '')
('ds9', '!=', 'test')
('bsdfsdf', '', '')

需要注意的几点:1)这使用逗号分隔符解析属性(因为我没有使用严格的 CSS)。2) 这要求模式采用以下格式:标签、ID、类、属性

第一个正则表达式执行标记,因此空格和“>”分隔选择器字符串的部分。这是因为我想用它来检查我自己的对象图:)

再次感谢!

于 2012-06-26T11:17:41.683 回答
1

我想你需要这样的东西。

(?P<tag>[a-zA-Z]+)?(\.(?P<class>[a-zA-Z0-9_-]+)?)?(#(?P<id>[a-zA-Z0-9_-])?)?\W*\{((?P<name>[a-zA-Z0-9-_]+?)=(?P<value>[a-zA-Z0-9-_]+?))*\}

对不起,如果它不起作用,我还没有测试它

于 2012-06-23T20:26:36.570 回答
1

绝对不要尝试使用单个正则表达式来执行此操作。正则表达式是出了名的难以阅读和调试,所以当你完成了这个任务的前 80% 并回去尝试修复错误时,代码将是一场噩梦。

相反,尝试编写函数,甚至是一个类,让你可以做你想做的事情。然后,您可以为每个特定任务使用相对简单的正则表达式,并在您的实现中使用更直观的语法。

class css_parser:

  def __init__(self):
    self.class_regexp = re.compile('\.[\w\-]*') # This is insufficient, but it's a start...

  def get_class(self, str):
    m = self.class_regexp.match(str)
    return m.group(0)

您需要查阅W3C CSS 规范,特别是第 4 节。

于 2012-06-23T20:29:02.957 回答