在我自己工作中,要處理各種不同電子病例模板的數據,一些電子病例數據存放於數據庫的大文本字段中,在我們自己系統中又要求重要的域要分開和提供接口供別人調用,我們需要把這些數據進行拆分,如拆分出:
入院情況;出院時間;住院經過;出院情況;出院醫囑;出院囑託;出院帶藥;入院診斷;出院診斷;病理診斷;
因爲模板不同,每個域的位置會不一樣或者沒有,所以我決定寫一個函數來處理,下面我說一下我的做法:
字段內容如:
<table id="table1" width="100%" border="0"> <tbody> <tr> <td align="center" colspan="6" style="height: 48px"><font color="#000000"><span class="title" id="_ctl0_C1_Label1">出院記錄</span> </font></td> </tr> <tr> <td style="width: 27%"><span class="boldText">姓名:</span> <span class="text" id="_ctl0_C1_lbName">王XXX</span></td> <td style="width: 25%"><span class="boldText">性別:</span> <span class="text" id="_ctl0_C1_lbSex">男性</span></td> <td style="width: 19%"><span class="boldText">年齡:</span> <span class="text" id="_ctl0_C1_lbAge">57歲</span></td> <td style="width: 29%"> </td> </tr> <tr> <td><span class="boldText">入院時間:</span> <span class="text" id="_ctl0_C1_tbInHosTime">2013-01-09</span></td> <td><span class="boldText">出院時間:</span> <span class="text" id="_ctl0_C1_tbOutHosTime">2013-01-15</span></td> <td><span class="boldText">住院天數:</span> <span class="text" id="_ctl0_C1_tbDays">6</span> 天</td> <td> </td> </tr> <tr> <td valign="top" colspan="4"><span class="boldText">入院診斷:</span> <span class="text" id="_ctl0_C1_tbInDiag">1.眩暈綜合徵 2.胃癌術後 3.左下肢靜脈血栓形成</span></td> </tr> <tr> <td valign="top" colspan="4"><span class="boldText">出院診斷:</span> <span class="text" id="_ctl0_C1_tbOutDiag">1.眩暈綜合徵 2.胃癌術後 3.左下肢靜脈血栓形成 4.2型糖尿病 5.輕度貧血(缺鐵性) 6.慢性乙型病毒性肝炎</span></td> </tr> <tr> <td valign="top" colspan="4"><span class="boldText">入院情況:</span><span class="txt-indent" id="_ctl0_C1_tbBlDiag">患者,男性,57歲,因“頭暈4小時”入院。浙一醫院胃癌行根治術後病史7月,術後病理活檢示胃潰瘍型低分化腺癌,部分印戒細胞癌伴淋巴結轉移性癌,已行8次化療,左下肢靜脈血栓形成病史7月,目前口服華法林片。查體:T37.0℃ P62次/分 R18次/分 BP123/68mmHg,神志清,呼吸平穩,口脣無發紺,鎖骨上淋巴結未及腫大,雙肺未及羅音,心率62次/分,律齊,未及雜音,腹平軟,無壓痛及反跳痛,腹部可見豎直手術疤痕,約8cm,癒合佳,肝脾肋下未及,雙下肢無水腫;專科檢查:右利手,言語流利,瞳孔等大約0.3cm,對光反射靈敏,口角無歪斜,伸舌居中,頸軟,指鼻試驗準確,四肢肌力5級,雙側巴氏徵陰性。輔助檢查:2012-05-14,本院,浙一醫院,胃鏡病理活檢示胃潰瘍型低分化腺癌,部分印戒細胞癌伴淋巴結轉移性癌;B超示左髂外靜脈、左股總靜脈、左股淺靜脈血栓形成,左下肢動脈血流通暢。 </span></td> </tr> <tr id="_ctl0_C1_tr_blbg"> <td valign="top" colspan="4"><span class="boldText">檢驗報告:</span><span class="txt-indent" id="_ctl0_C1_tbOutBlbg">2013-01-09 11:17查急常規+CRP+表抗:白細胞計數 4.0*10^9/L,血紅蛋白 90g/L,血小板計數 214*10^9/L,中性粒細胞比率 45.2%,平均血紅蛋白含量 25.6pg,平均血紅蛋白濃度 317g/L,血小板體積分佈寬度 9.2%,C-反應蛋白 1.4mg/L,乙肝表面抗原篩查 陽性;2013-01-09 11:24查凝血功能全套(急):國際標準化比值 1.19;2013-01-09 11:44查急診心肌酶譜+TnI定量:抗鏈球菌溶血素"O" 202IU/ml;2013-01-09 14:26查糖化血紅蛋白:HbA1C(NGSP) 7.9%,HbA1C(IFCC) 63mmol/mo,eGA(估算平均血糖) 9.97mmol/L,總糖化血紅蛋白 10.6%;2013-01-10 09:31查糖化血紅蛋白:HbA1C(NGSP) 7.7%;2013-01-10 09:50查凝血功能全套:國際標準化比值 0.99;2013-01-10 12:38查乙肝定量:乙肝表面抗原(定量) >250.00IU/ml,乙肝核心抗體(定量) 13.57S/CO;2013-01-10 13:25查糖耐量二次(G+I+C):空腹血糖 7.79mmol/L,餐後二小時血糖 13.03mmol/L,肝腎功能、血脂、電解質、甲狀腺功能、腫瘤標誌化驗基本正常;2013-01-12 11:27查凝血功能全套:國際標準化比值 1.11;2013-01-14 10:07查凝血功能全套:國際標準化比值 1.10。</span></td> </tr> <tr> <td valign="top" colspan="4"><span class="boldText">診治經過:</span> <span class="txt-indent" id="_ctl0_C1_tbProcess">予保護胃粘膜、抗凝,改善循環、營養神經及支持對症等治療。</span></td> </tr> <tr id="_ctl0_C1_trJc" style="display: none"> <td valign="top" colspan="4">診療期間主要檢查結果:</td> </tr> <tr id="_ctl0_C1_trJcjg" style="display: none"> <td valign="top" colspan="4"> </td> </tr> <tr> <td valign="top" colspan="4"><span class="boldText">出院情況:</span><span class="txt-indent" id="_ctl0_C1_tbOutHosRecord">患者血壓穩定,無頭痛、頭暈,無視物旋轉,飲食、睡眠良好,無噁心、嘔吐,無畏寒、發熱,無胸悶、氣促及呼吸困難,大小便無殊,查體:神志清,言語流利,對答切題,肺部聽診無羅音,心律齊,腹平軟,肝脾肋下未觸及,四肢肌力5級,右手握力稍弱,持物可,兩側巴氏徵(-);病情穩定,今要求出院,囑其注意休息,繼續用藥,定期複查。 </span></td> </tr> <tr> <td valign="top" colspan="4"><span class="boldText">療效評價:</span> <span class="text" id="_ctl0_C1_lbLxpj">不選</span></td> </tr> <tr> <td valign="top" colspan="4" style="height: 22px"><span class="boldText">出院醫囑:</span></td> </tr> <tr> <td valign="top" colspan="4"><span style="font-size: 14px"> 出院康復指導及注意事項:</span><span class="text" id="_ctl0_C1_lblZysx">低脂、糖尿病飲食,忌菸酒,適當活動,定期複查,繼續用藥,監測血糖、凝血功能。</span></td> </tr> <tr id="_ctl0_C1_trfzsj"> <td valign="top" colspan="4"><span style="font-size: 14px"> 複診時間:</span><span class="text" id="_ctl0_C1_lblFzsj">門診隨訪,監測血糖、凝血功能。</span></td> </tr> <tr id="_ctl0_C1_trcydy"> <td valign="top" colspan="4"><span style="font-size: 14px"> 出院帶藥:</span></td> </tr> <tr> <td class="txt-indent" valign="top" colspan="4"> <span id="_ctl0_C1_tbOutAdvice" style="font-size: 14px">甲鈷胺片500ug tid,呋喃硫胺片50mg tid。</span></td> </tr> <tr> <td colspan="4"> <table width="100%"> <tbody> <tr> <td width="70%"> </td> <td><span class="boldText">醫師簽名:</span><span class="text" id="_ctl0_C1_tbDoctor">李海霞</span></td> </tr> <tr> <td> </td> <td><span class="boldText">記錄日期:</span><span class="text" id="_ctl0_C1_tbDateTime">2013-01-14</span></td> </tr> </tbody> </table> </td> </tr> </tbody> </table>
首先進行去HTML或XML標記處理,使用正則表達式,sqlserver2005使用正則有兩種,一種是使用ole自動化調用vbscript,另一種是用c#編寫sqlserver CLR項目建立自定義函數,我使用的前者。正則函數摘於網上:
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
/*描述:正則式運算函數*/
CREATE function [dbo].[regexReplace]
(
@source varchar(5000), --原字符串
@regexp varchar(1000), --正則表達式
@replace varchar(1000), --替換值
@globalReplace bit = 0, --是否是全局替換
@ignoreCase bit = 0 --是否忽略大小寫
)
returnS varchar(1000) AS
begin
declare @hr integer
declare @objRegExp integer
declare @result varchar(5000)
exec @hr = sp_OACreate 'VBScript.RegExp', @objRegExp OUTPUT
IF @hr <> 0 begin
exec @hr = sp_OADestroy @objRegExp
return null
end
exec @hr = sp_OASetProperty @objRegExp, 'Pattern', @regexp
IF @hr <> 0 begin
exec @hr = sp_OADestroy @objRegExp
return null
end
exec @hr = sp_OASetProperty @objRegExp, 'Global', @globalReplace
IF @hr <> 0 begin
exec @hr = sp_OADestroy @objRegExp
return null
end
exec @hr = sp_OASetProperty @objRegExp, 'IgnoreCase', @ignoreCase
IF @hr <> 0 begin
exec @hr = sp_OADestroy @objRegExp
return null
end
exec @hr = sp_OAMethod @objRegExp, 'Replace', @result OUTPUT, @source, @replace
IF @hr <> 0 begin
exec @hr = sp_OADestroy @objRegExp
return null
end
exec @hr = sp_OADestroy @objRegExp
IF @hr <> 0 begin
return null
end
return @result
end
然後最主要的處理函數:
CREATE FUNCTION [dbo].[Func_GetDomainFromText](@value VARCHAR(MAX),@keyword VARCHAR(20))
RETURNS VARCHAR(MAX)
/*
* 描述:從備註信息中找出某部分數據,如出院診斷。
* 作者:羅毅
* 例子:select top 20 dbo.Func_GetDomainFromText(LeaveSituation,'出院診斷') FROM RS_MyTable
*/
BEGIN
--先去掉Html符號
DECLARE @T VARCHAR(MAX)
SET @T = dbo.regexReplace(@value,'<.+?>', '', 1, 1)
--預設置節點
DECLARE @Items TABLE(Name varchar(20),Pos INT)
INSERT INTO @Items VALUES('入院情況',CHARINDEX('入院情況',@T))
INSERT INTO @Items VALUES('出院時間',CHARINDEX('出院時間',@T))
INSERT INTO @Items VALUES('住院經過',CHARINDEX('住院經過',@T))
INSERT INTO @Items VALUES('出院情況',CHARINDEX('出院情況',@T))
INSERT INTO @Items VALUES('出院醫囑',CHARINDEX('出院醫囑',@T))
INSERT INTO @Items VALUES('出院囑託',CHARINDEX('出院囑託',@T))
INSERT INTO @Items VALUES('出院帶藥',CHARINDEX('出院帶藥',@T))
INSERT INTO @Items VALUES('入院診斷',CHARINDEX('入院診斷',@T))
INSERT INTO @Items VALUES('出院診斷',CHARINDEX('出院診斷',@T))
INSERT INTO @Items VALUES('病理診斷',CHARINDEX('病理診斷',@T))
DELETE FROM @Items WHERE Pos = 0
--獲取keyword對應的位置
DECLARE @p1 INT
DECLARE @p2 INT
DECLARE @F INT
DECLARE @Res VARCHAR(MAX)
SET @F = 5
SET @p1 = -1
SET @p2 = -1
SET @p1 = CHARINDEX(@keyword,@T)
IF @p1 <= 0 RETURN ''
SELECT TOP 1 @p2=Pos FROM @Items WHERE Pos > @p1 ORDER BY Pos
IF (@p2 <= @p1)
--當前關鍵字在組中位於最後,則取後面所有數據
SET @Res = SUBSTRING(@T,@p1+@F,len(@T)-@p1-@F)
ELSE
--這裏的偏移量5,是因爲文本中存在冒號,如“出院診斷:”
SET @Res = SUBSTRING(@T,@p1+@F,@p2-@p1-@F)
RETURN @Res
END
如有不足之處,希望大家指出,我即時修改。