正则表达式 - 将一个字符的序列替换为具有相同数量的另一个字符

时间:2011-09-07 17:26:29

标签: regex replace

假设我有一个这样的字符串:

=====

我想用这个替换它:

-----

我只想替换它,如果它有超过一定数量的那个角色(我们会说> 3)。

所以,这些应该是替代品:

=== -> ===
==== -> ----
===== -> -----

应用程序是我想用mark level替换markdown中的所有1级标题,而不更改嵌入的代码块。

我知道我可以这样做:

/=/-/g,但这会匹配任何带有等号(if (x == y))的内容,这是不可取的。

或者这个:

/===+/----/g,但这并不考虑原始匹配字符串的长度。

这可能吗?

4 个答案:

答案 0 :(得分:10)

可以使用Perl:

my $string = "===== Hello World ====";
$string =~ s/(====+)/"-" x length($1)/eg;
# $string contains ----- Hello World ----

Flag / e使得Perl在s ///的第二部分执行表达式。 你可以尝试使用oneliner:

perl -e '$ARGV[0] =~ s/(====+)/"-" x length($1)/eg; print $ARGV[0]' "===== Hello World ===="

答案 1 :(得分:4)

根据您使用的语言而定。基本上,在某些语言中,您可以将代码放在regexp的右侧,允许您执行以下操作:(这是perl):

s/(=+)/(length($1) > 3 ? "-" : "=") x length($1)/e

'e'标志告诉perl执行表达式右侧的代码,而不是仅仅将其解析为字符串。

答案 2 :(得分:1)

我也在寻找类似这样的纯正则表达式解决方案。我在SO上找不到一个,所以我解决了。

简短版本:here是正则表达式:

((?<====)=)|(=(?====))|((?<===)=(?==))|((?<==)=(?===))

这是我使用R到达那里的方式:

str <- " = == === ==== ===== ====== ======="

gsub("=(?====)",      "-", str, perl = TRUE) # (1) Pos. lookahead
gsub("(?<====)=",     "-", str, perl = TRUE) # (2) Pos. look-behing
gsub("(?<===)=(?==)", "-", str, perl = TRUE) # (3) Middle part for cases of 4 or 5 ='s (1/2)
gsub("(?<==)=(?===)", "-", str, perl = TRUE) # (4) Middle part for cases of 4 or 5 ='s (2/2)

# Combining all, we have:
gsub("((?<====)=)|(=(?====))|((?<===)=(?==))|((?<==)=(?===))", "-", str, perl = TRUE) # (5)

(1) = == === -=== --=== ---=== ----===
(2) = == === ===- ===-- ===--- ===----
(3) = == === ==-= ==--= ==---= ==----=
(4) = == === =-== =--== =---== =----==
(5) = == === ---- ----- ------ -------

较不复杂的正则表达式的替代方法(但需要3个步骤)

# First, deal with 4 & 5 equal signs with negative look-behind and lookahead
str <- gsub("(?<!=)={4}(?!=)", "----",     str, perl = TRUE) # (2.1)
str <- gsub("(?<!=)={5}(?!=)", "-----",    str, perl = TRUE) # (2.2)

# Then use regex (3) from above for 6+ equal signs
str <- gsub("((?<====)=)|(=(?====))", "-", str, perl = TRUE) # (2.3)

(2.1) = == === ---- ===== ====== =======
(2.2) = == === ---- ----- ====== =======
(2.3) = == === ---- ----- ------ -------

答案 3 :(得分:0)

专门针对此Markdown标题用例,您可以使用以下事实:它们总是出现在行的开头:

/(^=|(?<==)=)/-/

将替换所有在行首或前面带有'='的'='字符。

虽然它将在文本中加倍'=='……也许有人可以对此进行改进?