我正在嘗試撰寫一個小腳本(最好在 bash 中,但 python 或 perl 也可以)來屏蔽 SSN 的前 5 位數字(格式為 123456789 或 123-45-6789 - 所以它將輸出 XXXXX6789 或 XXX -XX-6789 分別)。輸入在一個文本檔案中。
我知道我應該能夠用 sed 做到這一點,但是我在創建正確的正則運算式時遇到了麻煩(然后我必須進行替換)。它應該正確處理所有這些用例:
123456789 needs to be matched.
123-45-6789 does, too.
Mask this 123-45-6789 SSN please
Don't miss 123456789 either.
123456789 should match.
123-45-6789 should also match.
As should 123456789
And 123-45-6789
But not 1234567890
1234567890 should also not match.
And 1234567890 is right out.
因此,SSN 可以出現在一行的開頭、中間某處或結尾。
輸出(例如,前兩行)應該屏蔽前 5 個數字,比如用 Xs):
XXXXX6789 needs to be matched.
XXX-XX-6789 does, too.
我設法得到一個 grep 正則運算式,它只正確匹配我想要的運算式:
grep '\b[0-9]\{3\}-\{0,1\}[0-9]\{2\}-\{0,1\}[0-9]\{4\}\b' testfile
我認為我應該能夠在 sed 或 awk 中使用分組來獲得我想要的結果,但是我嘗試過的所有方法都沒有奏效。
uj5u.com熱心網友回復:
使用sed
$ sed '/\<[0-9]\{9\}\>\|\<[0-9-]\{11\}\>/{s/[0-9]\{5\}/XXXXX/;s/[0-9]\{3\}-[0-9]\{2\}/XXX-XX/g}' input_file
XXXXX6789 needs to be matched.
XXX-XX-6789 does, too.
Mask this XXX-XX-6789 SSN please
Don't miss XXXXX6789 either.
XXXXX6789 should match.
XXX-XX-6789 should also match.
As should XXXXX6789
And XXX-XX-6789
But not 1234567890
1234567890 should also not match.
And 1234567890 is right out.
uj5u.com熱心網友回復:
使用 GNU awk 作為第三個 arg to match()and gensub()and \< \>word 邊界:
$ awk '
match($0,/(.*)(\<[0-9]{3}-?[0-9]{2})(-?[0-9]{4}\>.*)/,a) {
$0 = a[1] gensub(/[0-9]/,"X","g",a[2]) a[3]
}
1' file
XXXXX6789 needs to be matched.
XXX-XX-6789 does, too.
Mask this XXX-XX-6789 SSN please
Don't miss XXXXX6789 either.
XXXXX6789 should match.
XXX-XX-6789 should also match.
As should XXXXX6789
And XXX-XX-6789
But not 1234567890
1234567890 should also not match.
And 1234567890 is right out.
uj5u.com熱心網友回復:
perl -lpe 's/\b[0-9]{3}(-?)[0-9]{2}(-?)([0-9]{4})\b/XXX${1}XX$2$3/g'
您只需要捕獲最終將出現在輸出中的內容:(可能的)破折號和最后四位數字。而且,Perl 的正則運算式語法消除了不必要的反斜杠,這很好。
(具體來說,在 perl 正則運算式中,“魔術”函式總是附加到不帶反斜杠的標點符號或帶有反斜杠的字母數字;反斜杠標點符號總是使其不特殊。)
uj5u.com熱心網友回復:
假設前 8 行應該應用了掩碼(最后 3 行保持不變):
修改輸入檔案以在前 2 行中包含雙重匹配 SSN 模式:
$ cat testfile
123456789 needs to be matched (and again 123-45-6789)
123-45-6789 does, too (and again 123456789)
Mask this 123-45-6789 SSN please
Don't miss 123456789 either.
123456789 should match.
123-45-6789 should also match.
As should 123456789
And 123-45-6789
But not 1234567890
1234567890 should also not match.
And 1234567890 is right out.
sed使用 OP 正則運算式的修改版本的一個想法:
sed -r 's/\b([0-9]{3})(-{0,1})([0-9]{2})(-{0,1}[0-9]{4})\b/XXX\2XX\4/g' testfile
在哪里:
-r- 啟用擴展的正則運算式支持(無需轉義括號和大括號)([0-9]{3})- 匹配 3 位數字(第一個捕獲組)(-{0,1})- 匹配可選-(第二個捕獲組)([0-9]{2})- 匹配 2 個數字(第 3 個捕獲組)(-{0,1}[0-9]{4})- 匹配可選-4 位數字(第 4 個捕獲組)XXX\2XX\4- 將第一個捕獲組替換XXX為,按原樣列印第二個捕獲組,將第三個捕獲組替換為,XX按原樣列印第四個捕獲組g- 適用于一行中的所有匹配項
這會產生:
XXXXX6789 needs to be matched (and again XXX-XX-6789)
XXX-XX-6789 does, too (and again XXXXX6789)
Mask this XXX-XX-6789 SSN please
Don't miss XXXXX6789 either.
XXXXX6789 should match.
XXX-XX-6789 should also match.
As should XXXXX6789
And XXX-XX-6789
But not 1234567890
1234567890 should also not match.
And 1234567890 is right out
uj5u.com熱心網友回復:
Grep 反轉匹配正則運算式(固定):
grep -vE '([^0-9]|^)[0-9]{3}-?[0-9]{2}-?[0-9]{4}([^0-9]|$)' input-file.txt
grep 選項:
-v:反轉匹配(列印沒有匹配的所有內容)。-E:對模式使用擴展的正則運算式語法。
正則運算式詳細資訊:
([^0-9]|^):匹配非數字或行首。[0-9]{3}-?:匹配 3 位數字,可選地后跟一個破折號。[0-9]{2}-?: 匹配 2 位數字,可選地后跟一個破折號。[0-9]{4}: 匹配 4 位數字。([^0-9]|$):匹配非數字或行尾。
測驗
grep -vE '([^0-9]|^)[0-9]{3}-?[0-9]{2}-?[0-9]{4}([^0-9]|$)' <<'EOF'
123456789 needs to be matched.
123-45-6789 does, too.
Mask this 123-45-6789 SSN please
Don't miss 123456789 either.
123456789 should match.
123-45-6789 should also match.
As should 123456789
And 123-45-6789
But not 1234567890
1234567890 should also not match.
And 1234567890 is right out.
EOF
測驗輸出:
But not 1234567890
1234567890 should also not match.
And 1234567890 is right out.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/494019.html
上一篇:編碼-字串位元組長度
