以下sed语句的含义是什么?

时间:2018-02-02 01:23:27

标签: sed

@Html.EditorFor(model => model.Date, new { htmlAttributes = new { @class = "form-control" , id = "dates" } })

@Html.DropDownListFor(model => model.dayOff,
    new List<SelectListItem> {
        new SelectListItem { Text = "Select", Value="0" },
        new SelectListItem { Text = "Monday", Value="1" },
        new SelectListItem { Text = "Tuesday",Value= "2" },
    }, 
    new { @class = "form-control", onchange="test()", id ="drop1" })

输入:

sed 's/<img src=\"\([^"]*\).*/\1/g'

输出:

<img src="geo.yahoo.com/b?s=792600534"; height="1" width="1" style="position: absolute;" />

2 个答案:

答案 0 :(得分:0)

此部分是与捕获组匹配的正则表达式,后面称为\1(第一个捕获组)。它提取src属性的值。

First part if the regex -> <img src=\"
capturing group         -> \([^"]*\)
rest of the regex       -> .*

方括号内的表达式可以理解为:&#34;任何不是双引号的内容&#34;。

答案 1 :(得分:0)

sed是一种脚本语言。其s命令使用正则表达式执行替换。语法为s/regex/replacement/flags。在您的示例中,您有正则表达式

<img src=\"\([^"]*\).*

和替换

\1

和标志

g

正则表达式显然是在试图解析HTML,这值得你在一个温暖的地方找到一个地方,一个友好的绅士与干草叉帮助你解决激励问题。远在很远的地方,上帝不情愿地结束了一只毛茸茸的小猫的生命。

正则表达式包含一个捕获组,它只是括号之间匹配的文本。替换\1引用此捕获的文本。因此,简而言之,您将删除与围绕此捕获字符串匹配的部分。

s/foo\(bar\)baz/\1/

foobarbaz替换baz,从匹配的任何内容中检索“baz”部分,而不是硬编码替换字符串。

正则表达式.*可以任意次数匹配任何字符;正则表达式引擎将更喜欢最长,最左边的匹配。

正则表达式[^"]*匹配不是(换行符或"的单个字符,而*再次表示匹配尽可能多的匹配。所以"\([^"]*\)"找到一个双引号字符串,并捕获其内容;当匹配尽可能多的字符时,否定的"会阻止正则表达式匹配结束引号。 (如评论中所述,第一个"之前的反斜杠是不必要的,但基本上是无害的。它只是告诉我们写这个的人不是正则表达式向导。)

但是,您的示例只是隐含地包含.*匹配中的结束引用,它将简单地匹配从结束引号到行尾的所有内容。

g标志表示尽可能多次重复替换命令;因此,如果输入行包含多个匹配项,则将替换所有匹配项。 (如果没有g标志,sed将只替换它在一行上找到的第一个匹配。)但是由于你刚刚删除了该行的其余部分,因此该标志在这里实际上并不有用;只能有一场比赛。

使用干草叉的绅士不希望我告诉你这个,但这段代码不适合通用脚本。我们无法保证src元素的img属性会立即与img开头标记相邻,中间只有一个空格; HTML允许任意间距(包括换行),您可以使用其他属性,例如idalttitle,这些属性可以在src属性之前或之后。正确的解决方案是使用HTML解析器提取src标记的img属性,并正确理解周围的语法。

xmlstarlet sel -T -t -m "/img" -m "@src" -v '.' -n

...虽然src属性后的迷路分号是HTML语法违规;你的意见真的存在吗?

xmlstarlet命令行无耻地改编自https://stackoverflow.com/a/3174307/874188