gpt4 book ai didi

regex - 匹配两个标记内任意位置的单词,由空格或标记分隔

转载 作者:行者123 更新时间:2023-12-02 01:54:23 24 4
gpt4 key购买 nike

使用 Gnu sed,我可以只替换出现在两个标记之间的单词(但 它们之间的任何地方),只有当该单词在左侧分隔时起始标记或空格并在右侧由结束标记或空格分隔?与在单词的任一侧(标记之间)使用 \b 非常相似,但只允许空格(如果与开始/结束标记相邻,则不允许空白)作为分隔符。 \b 标记了“单词”和“非单词”字符之间的边界,并将 - 视为非单词字符,这在这种情况下是不希望的。到目前为止的工作和结果,以及下面的测试用例。

[详细信息:具体来说,我试图用其他类替换 HTML 文件中 class="..." 文本中的类。这可能是“不要使用正则表达式来处理 HTML”的另一个例子,但问题是如此有限(例如,我不在乎它是否碰巧匹配到开始标记之外; 我不关心嵌套),感觉它应该是可能的,如果可能的话,它会比我的下一个选择 Jsoup 更受欢迎(无论它多么酷和诱人)。它感觉像是一个正则表达式和/或 sed 学习机会。]

起始标记是:

\(\sclass\s*=\s*"\)

(yes, I need to capture it).

The ending marker is:

"

...where no " are allowed in-between (whether escaped in some way or not). So nice and contained, not requiring proper parsing. (I'll use a second command to handle the single quotes version.)

I want to match things like this (for example, there are several of them):

span\([0-9]\+\)

Here's what I have so far, changing spanN to col-md-N (but using \b, and thus not quite working correctly):

s/\(\sclass\s*=\s*"\)\([^"]*\)\bspan\([0-9]\+\)\b\([^"]*\)"/\1\2col-md-\3\4"/g

And it works nicely for this sample data:

<div class="blah span3 arg">This has span3 in it</div>
<div class="span3">This has span3 in it</div>
<div class="span3 arg">This has span3 in it</div>

给我想要的:

<div class="blah col-md-3 arg">This has span3 in it</div>
<div class="col-md-3">This has span3 in it</div>
<div class="col-md-3 arg">This has span3 in it</div>

但当然它也会改变以下内容:

<div class="blah x-span3 arg">This has x-span3 in it</div>
<div class="x-span3">This has x-span3 in it</div>
<div class="x-span3 arg">This has x-span3 in it</div>
<div class="blah span3-x arg">This has span3-x in it</div>
<div class="span3-x">This has span3-x in it</div>
<div class="span3-x arg">This has span3-x in it</div>

...这是不希望的。不用说 xxxspan3 也应该单独保留(当然 \b 版本会这样做)。

有没有可能让它改变那些?对于“开始”、“中间”和“结束”的情况,不重复表达三遍? (六次,如果你计算单引号排列。几十次 如果你计算我需要更改的所有其他内容。)

如果答案真的是“不,你不能”,那么,这是一个完全可以接受的答案,我会得到一个更大的锤子。


结语:仅供引用,这确实是“不要尝试使用正则表达式处理 HTML”的又一案例。虽然 Jerry 的回答确实满足了我的需要,但我越深入,就越清楚我需要的上下文比正则表达式所能提供的更多。我最终将 NodeJS 与 cheerio DOM 解析器一起使用,因为 cheerio 非常擅长将其对标记的更改最小化。

最佳答案

你可以试试这个正则表达式:

s/\(\sclass\s*=\s*"\)\(\([^"]*\)\( \)\)\?span\([0-9]\+\)\(\( \)\([^"]*\)\)\?"/\1\3\4col-md-\5\7\8"/g

[抱歉有点长]

我从(突出显示的更改)开始:

s/\(\sclass\s*=\s*"\?\)\([^"]*\)\([" ]\)span\([0-9]\+\)\([" ]\)\([^"]*\)/\1\2\3col-md-\4\5\6/g
^^ ^^^^^^^^ ^^^^^^^^ ^

我试图捕获 "span 之前的空格以及 span 中数字后面的任何两个空格。那还要求在替换中添加更多反向引用并删除必须调整正则表达式的最后一个引号,但由于 class=span 没有资格通过,我意识到我不能'不要只是将第一个引号设为可选或删除最后一个引号。

因此我从捕获组中删除了引号:

s/\(\sclass\s*=\s*"\)\([^"]*\)\( \)span\([0-9]\+\)\(" \)\([^"]*\)"/\1\2\3col-md-\4\5\6"/g
^^^^^ ^^^^^

现在,只有引号需要处理。由于我们只能有 "span ...span\d+",这意味着两者之间的所有内容都可以设为可选:

s/\(\sclass\s*=\s*"\)\(\(\([^"]*\)\( \)\)\?span\([0-9]\+\)\(\(" \)\([^"]*\)\)\?"/\1\2\3col-md-\4\5\6"/g
^^ ^^^^ ^^ ^^^^

唯一剩下的就是调整不同捕获组的反向引用:

s/\(\sclass\s*=\s*"\)\(\([^"]*\)\( \)\)\?span\([0-9]\+\)\(\( \)\([^"]*\)\)\?"/\1\3\4col-md-\5\7\8"/g
^^^^ ^^^^

关于regex - 匹配两个标记内任意位置的单词,由空格或标记分隔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21024346/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com