否定正则表达式

3
我有一个正则表达式来缩小由Laravel视图编译器生成的代码结果。 正则表达式只是在编译视图时缩小HTML。 我遇到了设置正则表达式以忽略以“:”和“@”开头的属性(例如... @click="hide(true)" :class="{collapsed: !open}">)的麻烦,因为alpinejs使用它们。
在HTML代码中:

<select
                                        id="version-switcher"
                                        :class="{test: true}"
                                        aria-label="Localhost version"
                                        class="appearance-none"
                                        @change="window.location = $event.target.value"
                                    >
                                                                                    <option  value="https://localhost">Test</option>
                                                                                    <option selected value="https://localhost">Foo</option>
                                                                            </select>

结果应该是:

<select id="version-switcher" :class="{test: true}" aria-label="Localhost version" class="appearance-none" @change="window.location = $event.target.value"><option value="https://localhost">Test</option><option selected value="https://localhost">Foo</option></select>

然而,输出为:

<select id="version-switcher":class="{test: true}" aria-label="Localhost version" class="appearance-none"@change="window.location = $event.target.value"><option value="https://localhost">Test</option><option selected value="https://localhost">Foo</option></select>

注意,以冒号开头的属性和以 @ 开头的属性不与前一个属性分开。正则表达式为:return preg_replace('/<!--(.*?)-->|\s\B/um', '', $html); 请问有人能帮我解决这个问题吗?

尝试将\B替换为[\B@:] - apokryfos
在这种情况下,不能使用 [\B@:]。 - Mauricio Mendoza
1个回答

1

您可以使用

preg_replace('~<!--[^-]*(?:-(?!->)[^-]*)*-->|\s+(?=\s[@:]?\w[\w-]*=|[<>])~u', '', $text)

请查看正则表达式演示

详情:

  • <!--[^-]*(?:-(?!->)[^-]*)*--> - 匹配 <!-- 字符串,然后是零个或多个非 - 字符,接着是零个或多个不紧跟着 ->- 字符,最后是零个或多个非连字符的字符。
  • | - 或者
  • \s+ - 一个或多个空格
  • (?=\s[@:]?\w[\w-]*=|[<>]) - 这些空格紧接着
    • \s[@:]?\w[\w-]*= - 一个空格,一个可选的 @:,一个单词字符,零个或多个单词或 - 字符,然后是一个 = 字符
    • | - 或者
    • [<>] - 一个 <> 字符。

优秀的解决方案,朋友Wiktor Stribiżew!他以不同的方式并用多行实现了相同的结果(我不喜欢)。我的解决方案是:$pattern = [ '/<!--(.*?)-->|\s\B/', '/<(.*?)>\s+/', '/([@:][a-zA-Z\d-]+=[\"\'][^\"\']*[\"\']\s*)/']; $replacement = [ '', '<$1>', ' $1$2'];。你的解决方案简单得多。谢谢! - Mauricio Mendoza
1
@MauricioMendoza 请注意,我的正则表达式部分匹配注释是采用展开循环原则编写的,因此它可能并不简单,但相当高效。\s\B\s(?=\s)是不正确的,因为它们也会删除值内部的空格,而不仅仅是标记元素之间的空格。 - Wiktor Stribiżew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接