正则表达式模式,用于将BEM字符串拆分为多个部分(PHP)

时间:2019-06-13 16:05:10

标签: php regex bem

我想通过PHP regex隔离字符串的块,元素和修饰符部分。我使用的BEM的样式是小写字母并带有连字符。例如:

this-defines-a-block__this-defines-an-element--this-defines-a-modifier

我的字符串总是按照上面的格式设置,因此正则表达式不需要过滤掉任何无效的BEM,例如,我永远不会有像这样的脏字符串:

This.defines-a-block__this-Defines-an-ELEMENT--090283

块,元素和修饰符的名称可以包含数字,因此我们可以采用以下任意组合:

this-is-block-001__this-is-element-001--modifier-002

最后,修饰符是可选的,因此并非每个字符串都有一个修饰符,例如:

this-is-a-block-001__this-is-an-element
this-is-a-block-002__this-is-an-element--this-is-an-optional-modifier

我正在寻找一些正则表达式来返回BEM标记的每个部分。每个字符串都将被隔离并单独发送到正则表达式,而不是作为一个组或多行字符串。以下内容分别发送:

# String 1
block__element--modifier

# String 2
block-one__element-one--modifier-one

# String 3
block-one-big__element-one-big--modifier-one-big

# String 4
block-one-001__element-one-001

会返回:

# String 1
block
element
modifier

# String 2
block-one
element-one
modifier-one

# String 3
block-one-big
element-one-big
modifier-one-big

# String 4
block-one-001
element-one-001

1 个答案:

答案 0 :(得分:3)

您可以使用3个捕获组,并使用?

将第三个捕获组设为可选

由于所有三个组都是小写字母,可以包含数字并且可以使用连字符作为定界符,因此可以使用字符类[a-z0-9]

您可以使用(?1)

将模式1重新用于组1
\b([a-z0-9]+(?:-[a-z0-9]+)*)__((?1))(?:--((?1)))?\b

说明

  • \b字边界
  • (第一个捕获组
    • [a-z0-9]+重复1次以上字符类中列出的内容
    • (?:-[a-z0-9]+)*重复0+次匹配-,并重复1+次字符类中的字符
  • )关闭第1组
  • __字面上匹配
  • ((?1))捕获第2组,递归第1组
  • (?:非捕获组
    • --字面上匹配
    • ((?1))捕获第3组,递归第1组
  • )?关闭非捕获组并将其设置为可选
  • \b字边界

Regex demo

或使用命名组:

\b(?<block>[a-z0-9]+(?:-[a-z0-9]+)*)__(?<element>(?&block))(?:--(?<modifier>(?&block)))?\b

Regex demo