在Windows Powershell(或dotNet)中进行文本包装和缩进去除
背景
Python有两个很实用的功能,分别叫“textwrap”和“dedent”。它们的作用就是对你提供的字符串进行处理,效果基本上是你能预料到的。
textwrap.wrap(text[, width[, ...]])
这个功能会把你输入的文本(一个字符串)进行换行处理,使得每一行的长度最多为指定的宽度。最后会返回一个包含处理后每一行的列表,注意最后不会有多余的换行符。
textwrap.dedent(text)
这个功能会去掉文本中每一行开头的公共空白部分。
http://docs.python.org/library/textwrap.html
问题:
在Windows PowerShell中,或者通过.NET的方法在PowerShell中,怎么实现这些功能呢?
3 个回答
1
在查看这个网站的Python结果时,发现正确的算法应该是在单词的边界处进行分割,而不是从文本中取固定长度的子串。
function wrap( [string]$text, [int]$width = 70 ) {
$line = ''
# Split the text into words.
$text.Split( ' '.ToCharArray( ) ) | % {
# Initialize the first line with the first word.
if( -not $line ) { $line = $_ }
else {
# For each new word, try to add it to the current line.
$next = $line + ' ' + $_
# If the new word goes over the limit,
# return the last line and start a new one.
if( $next.Length -ge $width ) { $line; $line = $_ }
# Otherwise, use the updated line with the new word.
else { $line = $next }
}
}
# Return the last line, containing the remainder of the text.
$line
}
这里还有一个不同的实现方式,叫做dedent
。
function dedent( [string[]]$lines ) {
# Find the shortest length of leading whitespace common to all lines.
$commonLength = (
$lines | % {
$i = 0
while( $i -lt $_.Length -and [char]::IsWhitespace( $_, $i ) ) { ++$i }
$i
} | Measure-Object -minimum
).Minimum
# Remove the common whitespace from each string
$lines | % { $_.Substring( $commonLength ) }
}
希望它们更详细的解释能让大家更明白一些 :)
3
这段代码写得很不负责任...
#requires -version 2.0
function wrap( [string]$text, [int]$width ) {
$i=0;
$text.ToCharArray() | group { [Math]::Floor($i/$width); (gv i).Value++ } | % { -join $_.Group }
}
function dedent( [string[]]$text ) {
$i = $text | % { $_ -match "^(\s*)" | Out-Null ; $Matches[1].Length } | sort | select -First 1
$text -replace "^\s{$i}"
}
1
我觉得你可以做一个命令行工具,按照你想要的方式来定制它。然后在你的命令行中使用这个工具。可能你还需要把你的脚本添加到PATH里,这样才能方便地调用它。