今天, 咱們討論一個使用正則表達式的問題. 題目源於某論壇, 內容以下:正則表達式
-----------------------需求-------------------------
原始文件:(編號,姓名,工資)
-------------------------------------------
00014367423811520328285王小勇-109.00
C0024367423811520214121刁曉用-7.25
00034367423811520214071喻大森409.00
10014367423811520212695呂二青234.18
10036227003818620017835王得丹679.49
D0046227003813550029454劉小波767.22
R0054367423811520212943徐小明559.32
但願獲得:
1︱4367423811520328285︱王小勇 | 0
2︱4367423811520214121︱刁曉用︱0
3︱4367423811520214071︱喻大森︱409
4︱4367423811520212695︱呂二青︱234.18
5︱6227003818620017835︱王得丹︱679.49
6︱6227003813550029454︱劉小波︱767.22
7︱4367423811520212943︱徐小明︱559.32
合計 | 2649.21
-----------------------------------------------
1) 加入序號
2)用 | 分割各項
3)去掉編號前4個字符
3) 工資項若爲負數,變爲 0
4)最後將工資爲正的,統計相加
-----------------------分析-------------------------
這種題目顯然使用正則表達式是最方便不過的. 首先將源文件保存爲salary.txt.
我把這個文件保存在 C:/Documents and Settings/Administrator 目錄下, 請你們注意, 儘可能避免使用管理員權限.
咱們要從原始數據中提取出3個信息: 編號, 姓名, 工資項.
它們都有各自固定的特色, 所以我使用下面的正則表達式分別匹配這三項:
^.{4}(?<id>/d+)
(?<name>[/p{IsCJKUnifiedIdeographs}]+)
(?<salary>[/d.]*)
匹配名稱時候, 我指定了中文, 日文, 韓文的特定集合. /p{IsCJKUnifiedldeographs}. 我想這是整個正則表達式的關鍵部分.
(?<>re)中, 指定正則表達式分組, <>中間是分組的名稱. re是正則表達式.
如今, 我給出最後的代碼樣子:
${C:salary.txt}
| `
ForEach-Object {
$total
=
0;
$id
=
1 } `
{
[void] (
$_
-match
'^.{4}(?<id>/d+)(?<name>[/p{IsCJKUnifiedIdeographs}]+)(?<salary>[/d.]*)'); `
$ofs
=
'|'; `
"$($id;$id++;$matches.id;$matches.name;'{0:F2}' -f [float]$matches.salary)"; `
$total
+=
$matches
.salary } `
{
"合計`t`t|$total" }
第一行從C:當前工做目錄讀取文件salary.txt, 而後經過管道, 傳遞給ForEach-Object命令. 首先我初始化了兩個變量$total和$id, 分別用於記錄最終的彙總值和每條記錄的id號.
接下來正則表達式從輸入中將信息分別匹配出來. 這些匹配的分組被保存在$matches哈希表中.
設置輸出分隔符爲|
拼接輸出的信息: id, 員工id, 姓名, 而後用-f運算符指定浮點數的格式.
並將每一個salary加到$total中.
最後打印彙總信息.
這裏我利用了一個小技巧, 由於題目要求負數等價於0, 所以正則表達式就沒有考慮負數的狀況. $matches.salary就是$null值. $null值能夠在數學運算中轉化爲數值0, 所以方便了整個腳本的實現.