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

Regex pattern for splitting BEM string into parts (PHP)

我想通过 PHP 正则表达式隔离字符串的块、元素和修饰符部分。我使用的 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

我正在为 return 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

会 return:

# 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

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

将第三个捕获组设为可选

由于所有 3 个组都是小写字母,可以包含数字并使用连字符作为分隔符,您可以使用字符 class [a-z0-9].

您可以使用 (?1)

为第 1 组重复使用该模式
\b([a-z0-9]+(?:-[a-z0-9]+)*)__((?1))(?:--((?1)))?\b

说明

  • \b字边界
  • ( 第一个捕获组
    • [a-z0-9]+ 将字符中列出的内容重复 1 次以上 class
    • (?:-[a-z0-9]+)* 重复 0+ 次匹配 - 和 1+ 次字符 class
  • ) 关闭组 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