Ruby 使用regex查找用4个空格标识的所有代码

Ruby 使用regex查找用4个空格标识的所有代码,ruby,regex,Ruby,Regex,给定一个textarea,类似于StackOverflow,我想用pre/code块包装代码(缩进4个空格)。我尝试使用以下正则表达式来查找代码: re = / # Match a MARKDOWN CODE section. (\r?\n) # $1: CODE must be preceded by blank line ( # $2: CODE contents (?:

给定一个textarea,类似于StackOverflow,我想用pre/code块包装代码(缩进4个空格)。我尝试使用以下正则表达式来查找代码:

re = / # Match a MARKDOWN CODE section.
    (\r?\n)              # $1: CODE must be preceded by blank line
    (                    # $2: CODE contents
      (?:                # Group for multiple lines of code.
        (?:\r?\n)+       # Each line preceded by a newline,
        (?:[ ]{4}|\t).*  # and begins with four spaces or tab.
      )+                 # One or more CODE lines
      \r?\n              # CODE folowed by blank line.
    )                    # End $2: CODE contents
    (?=\r?\n)            # CODE folowed by blank line.
    /x
result = subject.gsub(re, '\1<pre>\2</pre>')
re=/#匹配降价代码部分。
(\r?\n)#$1:代码前面必须有空行
(#$2:代码内容
(?:#多行代码的分组。
(?:\r?\n)+每行前面都有换行符,
(?:[{4}|\t)。*#并以四个空格或制表符开头。
)+#一个或多个代码行
\r?\n#代码按空行折叠。
)#结束$2:代码内容
(?=\r?\n)#代码按空行折叠。
/x
结果=subject.gsub(re,'\1\2')
但这不起作用,以下是Rubular中的示例:


关于如何使这个正则表达式与代码匹配的任何建议允许我在代码周围包装一个pre/code标记吗?谢谢

如果要匹配整行,请不要显式匹配
(?:\r?\n)+
,而是使用
^
$
。试一试

s = "before\n    indent1\n    indent2\nmiddle\n     indent1\nafter"
p s.gsub(/((?:(?:[ ]{4}|\t).*(?:\r?\n|$))+)/x, '<pre>\1</pre>')

如果要匹配整行,请不要显式匹配
(?:\r?\n)+
,而是使用
^
$
。试一试

s = "before\n    indent1\n    indent2\nmiddle\n     indent1\nafter"
p s.gsub(/((?:(?:[ ]{4}|\t).*(?:\r?\n|$))+)/x, '<pre>\1</pre>')

我认为你们的模式需要两个新的行在开始匹配

也许是这样<代码>((?:(?:[]{4}\t)。*(?:\r?\n |$)+)?
如果最后一行缩进且没有新行,$用于匹配)

红宝石:

s=“在\n缩进1\n缩进2\n中间\n缩进1\n之后”
p s.gsub(/((?:(?:[]{4}|\t)。*(?:\r?\n |$)+)/x,“\1”)
输出:

(^\s*$\n|\A)                                # Capt grp 1, block is preceeded by a blank line or begin of string
(                                           # Begin "Capture group 2", start of pre/code block
   ^(?:[ ]{4}|\t) .* [^\s] .* $ \n?            # First line of code block (note - lines must contain at least 1 non-whitespace character)
   (?:                                         # Start "Optionally, get more lines of code"
       (?: ^ \s* $ \n? )*                         # Many optional blank lines
       ^(?:[ ]{4}|\t) .* [^\s] .* $ \n?           # Another line of code 
   )*                                          # End "Optionally, get more lines of code", do 0 or more times
)                                           # End "Capture group 2", end of pre/code block
“之前\n缩进1\n缩进2\n中间\n缩进1\n之后”

我认为你的模式需要在开头添加两行新代码才能匹配

也许是这样<代码>((?:(?:[]{4}\t)。*(?:\r?\n |$)+)?
如果最后一行缩进且没有新行,$用于匹配)

红宝石:

s=“在\n缩进1\n缩进2\n中间\n缩进1\n之后”
p s.gsub(/((?:(?:[]{4}|\t)。*(?:\r?\n |$)+)/x,“\1”)
输出:

(^\s*$\n|\A)                                # Capt grp 1, block is preceeded by a blank line or begin of string
(                                           # Begin "Capture group 2", start of pre/code block
   ^(?:[ ]{4}|\t) .* [^\s] .* $ \n?            # First line of code block (note - lines must contain at least 1 non-whitespace character)
   (?:                                         # Start "Optionally, get more lines of code"
       (?: ^ \s* $ \n? )*                         # Many optional blank lines
       ^(?:[ ]{4}|\t) .* [^\s] .* $ \n?           # Another line of code 
   )*                                          # End "Optionally, get more lines of code", do 0 or more times
)                                           # End "Capture group 2", end of pre/code block
“之前\n缩进1\n缩进2\n中间\n缩进1\n之后”

我认为您的一个新行捕获是多余的。您可以在关闭
s
标志的情况下使用
^
$
来匹配EOL而不是EOL,这是一种比尝试匹配换行符更好的模式

尝试以下模式:


我认为你的一条新线截图是多余的。您可以在关闭
s
标志的情况下使用
^
$
来匹配EOL而不是EOL,这是一种比尝试匹配换行符更好的模式

尝试以下模式:


我认为有一种脱离代码模式的方法,任何尾随的换行符后面都没有制表符或4个空格。不确定,但连续的换行符不会包含在代码块中

我不太了解Ruby的正则表达式选项,但这似乎有效:

((?:^(?:[]{4}\t)。*$(?:\r?\n |\z))+)
理论上,它是多行模式

只需更换

Ruby代码-


正则表达式=/(^\s*$\n |\A)(^(?:[]{4}}\t)。*[^\s].$\n?(?:(?:^\s*$\n?*)^(?:[[]{4}\t.*[^\s].$\n?*)/;
数据收集
你好,WorldSasdasdfasdfasdf
这是我的
asdfasdfasdfasdfasdf
sdfg
#YYYY{
身高:100%;
最小高度:800px;
右边距:20px;
位置:相对位置;
}
#ZZZZZZ{
身高:100%;
溢出:隐藏;
}';
# ---
结果=data.gsub(regex){
||
x=2美元;

##构造返回值“\1我认为有一种退出代码模式的方法,任何尾随的换行符后面都没有制表符或4个空格。不确定,但连续的换行符不会包含在代码块中

我不太了解Ruby的正则表达式选项,但这似乎有效:

((?:^(?:[]{4}\t)。*$(?:\r?\n |\z))+)
理论上,它是多行模式

只需更换

Ruby代码-


正则表达式=/(^\s*$\n |\A)(^(?:[]{4}}\t)。*[^\s].$\n?(?:(?:^\s*$\n?*)^(?:[[]{4}\t.*[^\s].$\n?*)/;
数据收集
你好,WorldSasdasdfasdfasdf
这是我的
asdfasdfasdfasdfasdf
sdfg
#YYYY{
身高:100%;
最小高度:800px;
右边距:20px;
位置:相对位置;
}
#ZZZZZZ{
身高:100%;
溢出:隐藏;
}';
# ---
结果=data.gsub(regex){
||
x=2美元;

##构造返回值“\1谢谢,我试过了,但是没有单独匹配每一行,使每一行代码都围绕每个活动代码而不是围绕整个代码块一次?我认为如果您希望捕获组跨越多行,您需要显式匹配新行,或者?@MattiasWadman我不确定我是否理解question。但给定一块代码,我想用一个标记将其包装一次,就像在缩进w 4空格时StackOverflow所做的那样。想法?谢谢,我尝试过,但这并不是单独匹配每一行,使每一行代码都围绕每个活动代码而不是围绕整个代码块包装一次?我认为您需要明确匹配新行如果你想让捕获组跨越多行,或者?@MattiasWadman我不确定我是否理解这个问题。但是给定一段代码,我想用一个标记将其包装一次,就像你缩进w 4空格时StackOverflow所做的那样。想法?谢谢,但这是发现错误的匹配,请参见示例:你的意思是“不要理解我”?当我看hmmIt时,我不想匹配它,如果能够修复原始正则表达式就太好了:rubular.com/r/KyksYmQOI2--出于某种原因,如果在开始时发现一个错误匹配,但这是发现一个错误匹配,请参见示例:你的意思是“不要理解我”?我不想匹配,当我看hmmIt时,如果能够修复原始正则表达式就太好了:rubular.com/r/KyksYmQOI2--出于某种原因,如果在开始时发现错误匹配,那么能够修复原始正则表达式就太好了:---出于某种原因
(^\s*$\n|\A)                                # Capt grp 1, block is preceeded by a blank line or begin of string
(                                           # Begin "Capture group 2", start of pre/code block
   ^(?:[ ]{4}|\t) .* [^\s] .* $ \n?            # First line of code block (note - lines must contain at least 1 non-whitespace character)
   (?:                                         # Start "Optionally, get more lines of code"
       (?: ^ \s* $ \n? )*                         # Many optional blank lines
       ^(?:[ ]{4}|\t) .* [^\s] .* $ \n?           # Another line of code 
   )*                                          # End "Optionally, get more lines of code", do 0 or more times
)                                           # End "Capture group 2", end of pre/code block

regex = /(^\s*$\n|\A)(^(?:[ ]{4}|\t).*[^\s].*$\n?(?:(?:^\s*$\n?)*^(?:[ ]{4}|\t).*[^\s].*$\n?)*)/;

data = '
Hello Worldsasdasdffasdfasdf  asdf

    thisdqweee

    asdfasdfasdfasdf
sdfg

    #YYYY {
    height: 100%;
    min-height: 800px;
    margin-right: 20px;
    position: relative;
    }


    #ZZZZZZ {
    height: 100%;
    overflow: hidden;
    }';


# ---
result = data.gsub(regex) {
   ||
   x=$2;
     ## Construct the return value '\1<pre><code>\2</code></pre>'.
     ## But, trim each line with 1 to 4 leading spaces (or a tab with regex on the bottom).
     ## They are not necessary now, they are replaced with a code block.

   $1 + '<pre><code>' +   x.gsub(/^[ ]{1,4}/, '') + '</code></pre>'
};

# Note - Tabs can be trimed too, use : x.gsub(/^(?:[ ]{1,4}|\t)/,'') in the above

print result;