前言
最近接受了3個項目的洗禮,出差近3個月,各種北京、廣州、昆明來回奔波,好久沒寫博客了,之前我覺得我遇到的問題都比較零散所以就一篇博客寫一大堆,這樣導致文章太長,而且不方便填寫關鍵字,所以之后這個系列我就以單個問題的形式來描述,望廣大博友多多賜教~~
正文
我們知道在Binding的過程中是可以通過轉換器來加工數據傳輸值的,我們當然希望ViewModel的代碼越少越好,通用性越強越好,但是要如何才能做到萬能呢??當然要借助強大的正則表達式了~~轉換的過程我們可以看成是一個值的替換過程,如果能用上則表達式的替換功能,其參數可以在View里配置,這樣同用性就很強了。
例如我們需要處理以下3個問題:
示例1:(“1”轉為“男”,“0”轉為“女”)
示例2:(“1988-10-08”轉為“1988年10月08日”)
示例3:解析身份證信息(梁通通,男,漢,1988-10-08,環城東路304號,53250219881008xxxx,龐龍區公安局,1900-05-06,2100-15-09,雲南省昆明市XX區XXXXX)單獨提取姓名,性別等等.....
轉換器代碼:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Globalization;
using System.Text.RegularExpressions;
namespace CopSurface
{
[ValueConversion(typeof(string), typeof(String))]
public class RegexConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return RegexReplace(parameter,value);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return RegexReplace(parameter, value);
}
/// <summary>
/// 用正則表達式對值進行多次替換。
/// </summary>
/// <param name="parameter">替換參數--格式為"patternStr-replacement,patternStr-replacement,..."
/// "@"前面為要匹配的正則表達式,后面為要替換的表達式。每一次用"~"隔開</param>
/// <param name="value">要替換的值</param>
/// <returns>替換結束的值</returns>
private object RegexReplace(object parameter, object value)
{
string str = parameter as string;
string strValue = value.ToString();
string[] strList = str.Split('~');
foreach (string item in strList)
{
string[] reg = item.Split('@');
strValue = Regex.Replace(strValue.ToString(), reg[0], reg[1]);
}
return strValue;
}
}
}
分隔符我是找了則表達式基本語法里沒有的~@符號,當然了第一版沒有考慮通配符的問題,有待以后改進
示例1:(1轉為男,0轉為女)
<TextBlock Text="{Binding data[sex],Converter={StaticResource RegexConverter},ConverterParameter='1|true@男~0|false@女~[2-9]@'}"/>
這樣當data[sex]==1或者true是顯示就為男,輸入2就為女,輸入其他的數字就不顯示。
示例2:(1988-10-08轉為1988年10月08日)
<TextBlock Text="{Binding data[Birthday], ConverterParameter=^\\d{4}@$0年~-\\d{2}-@$0月~-@~$@$0日, Converter={StaticResource RegexReplace}}"/>
當然了這只是其中的一個用法,這個轉換器也可以用來做一些數據驗證,比如輸入的值匹配不上數字就替換為空 [^0-9]@,這樣就屏蔽了英文字母了。
示例3:解析身份證信息(梁通通,男,漢,1988-10-08,環城東路304號,53250219881008xxxx,龐龍區公安局,1900-05-06,2100-15-09,雲南省昆明市XX區XXXXX)提取出姓名
<TextBlock Text="{Binding data[IDCard],ConverterParameter=^(\\w+)\,(\\w+)\,(\\w+)\,(\\d{4}-\\d{2}-\\d{2})\,(\\w+)\,(\\w+)\,(\\w+)\,(\\d{4}-\\d{2}-\\d{2})\,(\\d{4}-\\d{2}-\\d{2})\,(\\w+)@$1, Converter={StaticResource RegexReplace}}" />
本人為了身份證仔細研究了正則表達式得出的以上結果。@之前為匹配整個身份證信息的正則表達式,然后用括號把獨立的信息分組。@后的$1就為分組的第一項結果即text實際內容為 梁通通。想要獲取生日就用$4,然后再用~鏈接實例2的表達式就可以轉為年月日~~~
這個轉換器的優點在於適應性強,缺點在於可讀性弱,這么一大堆看着都眼花,而且必須對正則表達式有一定的了解,本人對正則表達式的了解處於初級階段,相信各位大大可以用出更牛X的效果,歡迎各位博友提出寶貴的建議~
使用中可以先用 RegeX 3這個軟件替換出自己想要的結果,然后再復制進去,RegeX 3 還可以查看每一個分組的結果哦。
由於有了正則表達式的幫助可以說這個轉換器的潛力是無窮的,本人也只是昨天認真學習了下,更多關於正則表達式的使用推薦看這個:http://deerchao.net/tutorials/regex/regex.htm