找回密码
 加入
搜索
查看: 7413|回复: 14

[原创] _StringPad 字串左右補齊

[复制链接]
发表于 2008-6-2 20:02:46 | 显示全部楼层 |阅读模式
假如有個欄位是要填 3 位數的民國年,像是 097 這一類的話,若只輸入 97 這樣的 2 位數時,就要在前面多幫它補一個 0 或是空格好湊成 3 位數。這種方法叫做 PadLeft

何謂 PadLeftPadLeft 是將指定的字串靠右對齊,以空格或是指定的字元在左側填補至指定的長度

那既然有 PadLeft,那當然也有 PadRight 囉。PadRight 是跟 PadLeft 相反的,PadRight 是將指定的字串靠左對齊,以空格或是指定的字元在右側填補至指定的長度

這邊筆者提供 3 種不同的方式來達到 Pad 的效果。

1.使用 String UDF 中的 _StringRepeat 函式
 
#cs
版本:AutoIt v3 3.2.12.0
環境:Windows XP SP2
#ce
;載入 String 的 UDF
#include <String.au3>
#cs
函式名稱:
        _StringPad
函式描述:
        依指定的符號、長度及方向(左右)來補齊字串
需要參數:
        $string                要處理的字串
        [$length]        如果字串不滿 $length 則使用 $sign 補滿,預設為 $string 的長度
        [$sign]                用來補滿用的字串(符號),預設為 " "(空白)
        [$direction]        Pad 的方式,預設為 PadRight
回傳型態:
        String                Pad 後的字串
注意事項:
        需 #include <String.au3>
#ce
Func _StringPad($string, $length = -1, $sign = -1, $direction = 1)
 
 ;若 $length 為 -1 時則 $length 值為 $string 的長度
 If Not $length Then $length = StringLen($string)
 ;若 $sign 為 -1 時則 $sign 值為 " "(空白)
 If Not IsString($sign) Then $sign = " "
 ;如果 $string 長度沒有小於 $length 時則直接回傳
 If StringLen($string) >= $length Then return $string
 
    If $direction = 1 Then        ;PadRight
        Return $string & _StringRepeat($sign, $length - StringLen($string))
    Else                        ;PadLeft
        Return _StringRepeat($sign, $length - StringLen($string)) & $string
    EndIf
EndFunc

注意:因有使用到 _StringRepeat() 所要要記得 #include

2.使用遞迴
 
#cs
版本:AutoIt v3 3.2.12.0
環境:Windows XP SP2
#ce
#cs
函式名稱:
  _StringPad
函式描述:
  依指定的符號、長度及方向(左右)來補齊字串
需要參數:
  $string         要處理的字串
  [$length]       如果字串不滿 $length 則使用 $sign 補滿,預設為 $string 的長度
  [$sign]         用來補滿用的字串(符號),預設為 " "(空白)
  [$direction]    Pad 的方式,預設為 PadRight
回傳型態:
  String          Pad 後的字串
#ce
Func _StringPad($string, $length = -1, $sign = -1, $direction = 1)
 
 ;若 $length 為 -1 時則 $length 值為 $string 的長度
 If Not $length Then $length = StringLen($string)
 ;若 $sign 為 -1 時則 $sign 值為 " "(空白)
 If Not IsString($sign) Then $sign = " "
 ;如果 $string 長度沒有小於 $length 時則直接回傳
 If StringLen($string) >= $length Then return $string
 If $direction = 1 Then ;PadRight
  Return _StringPad($string & $sign, $length, $sign, $direction)
 Else                   ;PadLeft
  Return _StringPad($sign & $string, $length, $sign, $direction)
 EndIf
EndFunc


3.使用迴圈
 
#cs
版本:AutoIt v3 3.2.12.0
環境:Windows XP SP2
#ce
#cs
函式名稱:
  _StringPad
函式描述:
  依指定的符號、長度及方向(左右)來補齊字串
需要參數:
  $string         要處理的字串
  [$length]       如果字串不滿 $length 則使用 $sign 補滿,預設為 $string 的長度
  [$sign]         用來補滿用的字串(符號),預設為 " "(空白)
  [$direction]    Pad 的方式,預設為 PadRight
回傳型態:
  String          Pad 後的字串
#ce
Func _StringPad($string, $length = -1, $sign = -1, $direction = 1)
 
 ;若 $length 為 -1 時則 $length 值為 $string 的長度
 If Not $length Then $length = StringLen($string)
 ;若 $sign 為 -1 時則 $sign 值為 " "(空白)
 If Not IsString($sign) Then $sign = " "
 ;如果 $string 長度沒有小於 $length 時則直接回傳
 If StringLen($string) >= $length Then return $string
 
 ;計算要補幾位
 $length = $length - StringLen($string)
 
 If $direction = 1 Then ;PadRight
  For $i = 1 To $length
   $string &= $sign
  Next
 Else                   ;PadLeft
  For $i = 1 To $length
   $string = $sign & $string
  Next
 EndIf
 
 Return $string
EndFunc


讓我們先來看看怎樣使用吧:
 
;宣告變數
Local $str = "Hello"
;補滿長度為 10,補滿的符號及方式使用預設
ConsoleWrite(_StringPad($str, 10) & @CRLF)
;補滿長度為 10,補滿的符號為"#",方式使用預設
ConsoleWrite(_StringPad($str, 10, "#") & @CRLF)
;補滿長度為 10,補滿的符號為"#",方式為 Left
ConsoleWrite(_StringPad($str, 10, "#", 0) & @CRLF)


執行結果

Hello 
Hello#####
#####Hello


因筆者把這 3 種函式名稱都寫的一樣,且所需的參數也是一樣,因此使用的方法都是一樣的,所以要用那一種方法是沒什麼差的。另外因為第 1 種方式還要額外 #include ,所以也是一種考量啦!

筆者會比較傾向第 3 種方式,除了不用再引用額外的 UDF 之外,其實 _StringRepeat 函式 中用的方式也是迴圈的方式來處理的。

[ 本帖最后由 abgne 于 2008-6-2 20:05 编辑 ]
发表于 2008-6-6 21:03:28 | 显示全部楼层
用stringformat不是更好
发表于 2008-6-8 07:01:07 | 显示全部楼层
为什么要用繁体字呢?有些看不懂呀~!
发表于 2008-6-8 07:04:11 | 显示全部楼层
stringformat 如何用,有没有中文说明.
发表于 2008-6-8 07:30:42 | 显示全部楼层

回复 3# bing614 的帖子

台湾省的AU3朋友。。。
发表于 2008-6-8 07:31:32 | 显示全部楼层

回复 4# bing614 的帖子

测试几次就行。。。stringformat的确非常不错。
 楼主| 发表于 2008-6-9 16:55:59 | 显示全部楼层
當時也有試過StringFormat()...

不過有些結果試不出來
如果我要用s或是%這類的符號來填滿的話...
小弟就不知道該如何使用了...不知道pcbar版大或其它網友是否能指導一下..
发表于 2008-6-21 15:39:55 | 显示全部楼层

速度测试

经测试,还是第三种方法好使。
递归的耗时几乎是循环的10倍,数据量大的情况下会很成问题。
测试结果:
+>15:33:05 AU3Check ended.rc:0
>Running:(3.2.12.1):e:devAutoIt3autoit3.exe "C:Documents and SettingsJeff桌面新建 AutoIt v3 Script.au3"   
使用UDF函式运算总共耗时 9.93 秒!
使用遞迴运算总共耗时 76.493 秒!
使用迴圈运算总共耗时 8.206 秒!
+>15:34:40 AutoIT3.exe ended.rc:0
测试代码:
#include <String.au3>
Dim $i, $test, $begin1, $begin2, $begin3, $max = 100000
;
$begin1 = TimerInit()
For $i = 1 To $max
        $test = Random(1, $max, 1)
        $test = _StringPad1($test, 40)
Next
ConsoleWrite("使用UDF函式运算总共耗时 " & Round(TimerDiff($begin1) / 1000, 3) & " 秒!" & @CRLF)
;
$begin2 = TimerInit()
For $i = 1 To $max
        $test = Random(1, $max, 1)
        $test = _StringPad2($test, 40)
Next
ConsoleWrite("使用遞迴运算总共耗时 " & Round(TimerDiff($begin2) / 1000, 3) & " 秒!" & @CRLF)
;
$begin3 = TimerInit()
For $i = 1 To $max
        $test = Random(1, $max, 1)
        $test = _StringPad3($test, 40)
Next
ConsoleWrite("使用迴圈运算总共耗时 " & Round(TimerDiff($begin3) / 1000, 3) & " 秒!" & @CRLF)
;
;1.使用 String UDF 中的 _StringRepeat 函式
Func _StringPad1($string, $length = -1, $sign = -1, $direction = 1)
        ;若 $length 為 -1 時則 $length 值為 $string 的長度
        If Not $length Then $length = StringLen($string)
        ;若 $sign 為 -1 時則 $sign 值為 " "(空白)
        If Not IsString($sign) Then $sign = " "
        ;如果 $string 長度沒有小於 $length 時則直接回傳
        If StringLen($string) >= $length Then Return $string
        If $direction = 1 Then ;PadRight
                Return $string & _StringRepeat($sign, $length - StringLen($string))
        Else ;PadLeft
                Return _StringRepeat($sign, $length - StringLen($string)) & $string
        EndIf
EndFunc   ;==>_StringPad1
;
; 2.使用遞迴
Func _StringPad2($string, $length = -1, $sign = -1, $direction = 1)
        ;若 $length 為 -1 時則 $length 值為 $string 的長度
        If Not $length Then $length = StringLen($string)
        ;若 $sign 為 -1 時則 $sign 值為 " "(空白)
        If Not IsString($sign) Then $sign = " "
        ;如果 $string 長度沒有小於 $length 時則直接回傳
        If StringLen($string) >= $length Then Return $string
        If $direction = 1 Then ;PadRight
                Return _StringPad2($string & $sign, $length, $sign, $direction)
        Else ;PadLeft
                Return _StringPad2($sign & $string, $length, $sign, $direction)
        EndIf
EndFunc   ;==>_StringPad2
;
; 3.使用迴圈
Func _StringPad3($string, $length = -1, $sign = -1, $direction = 1)
        ;若 $length 為 -1 時則 $length 值為 $string 的長度
        If Not $length Then $length = StringLen($string)
        ;若 $sign 為 -1 時則 $sign 值為 " "(空白)
        If Not IsString($sign) Then $sign = " "
        ;如果 $string 長度沒有小於 $length 時則直接回傳
        If StringLen($string) >= $length Then Return $string
        ;計算要補幾位
        $length = $length - StringLen($string)
        If $direction = 1 Then ;PadRight
                For $i = 1 To $length
                        $string &= $sign
                Next
        Else ;PadLeft
                For $i = 1 To $length
                        $string = $sign & $string
                Next
        EndIf
        Return $string
EndFunc   ;==>_StringPad3
发表于 2008-10-2 19:58:25 | 显示全部楼层
不错。。有学了点东西
发表于 2008-10-6 19:09:38 | 显示全部楼层
ConsoleWrite(StringFormat("%10s\n",'hello'))
ConsoleWrite(StringFormat("%-10s\n",'hello'))
发表于 2009-11-11 22:52:31 | 显示全部楼层
有学了点东西
发表于 2011-1-1 20:43:17 | 显示全部楼层
繁体字看起来不太认识
发表于 2011-1-2 01:11:57 | 显示全部楼层
已经下载,感谢分享, 呵呵
发表于 2018-11-13 14:41:30 | 显示全部楼层
谢谢分享,学习学习
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-11-21 18:42 , Processed in 0.073737 second(s), 21 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表