在我自己工作中,要处理各种不同电子病例模板的数据,一些电子病例数据存放于数据库的大文本字段中,在我们自己系统中又要求重要的域要分开和提供接口供别人调用,我们需要把这些数据进行拆分,如拆分出:
入院情况;出院时间;住院经过;出院情况;出院医嘱;出院嘱托;出院带药;入院诊断;出院诊断;病理诊断;
因为模板不同,每个域的位置会不一样或者没有,所以我决定写一个函数来处理,下面我说一下我的做法:
字段内容如:
<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 ONset QUOTED_IDENTIFIER ONgo/*描述:正则式运算函数*/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,@[email protected],len(@T)-@p1-@F) ELSE --这里的偏移量5,是因为文本中存在冒号,如“出院诊断:” SET @Res = SUBSTRING(@T,@[email protected],@p2-@p1-@F) RETURN @ResEND
如有不足之处,希望大家指出,我即时修改。
- 2楼daling535昨天 11:07
- 4 rt`1
- 1楼daling535昨天 11:07
- 3