Sql 检测子字符串
我有很多需要整理的数据,其中一个字段既包含车辆的品牌/型号,也包含reg,有时用破折号(-)分隔,但有时不是。以下是此类字符串的示例: 车辆模型-TU69YUP 车辆模型-TU69是的 TU69YUP汽车模型 图69汽车模型是的 还有一些其他的变化,但它们是我遇到的主要变化。是否有一种方法可以可靠地检查所有数据,并将车辆reg从模型中分离出来 这些数据目前包含在一个Paradox数据库中,我没有任何问题。我没有数据库中包含的所有车型和名称的列表,同样,我也没有牌照列表Sql 检测子字符串,sql,string,delphi,filtering,Sql,String,Delphi,Filtering,我有很多需要整理的数据,其中一个字段既包含车辆的品牌/型号,也包含reg,有时用破折号(-)分隔,但有时不是。以下是此类字符串的示例: 车辆模型-TU69YUP 车辆模型-TU69是的 TU69YUP汽车模型 图69汽车模型是的 还有一些其他的变化,但它们是我遇到的主要变化。是否有一种方法可以可靠地检查所有数据,并将车辆reg从模型中分离出来 这些数据目前包含在一个Paradox数据库中,我没有任何问题。我没有数据库中包含的所有车型和名称的列表,同样,我也没有牌照列表 该项目是用Delphi/S
该项目是用Delphi/SQL编写的,因此如果可能的话,我更愿意使用其中任何一种。字[空格]字 然后,您可以遍历它们,如果遇到没有破折号的空白,请插入破折号。然后按正常方式拆分。下面是一个代码示例。 它将检查
-
,并删除许可证号码中可能的空格
注意:(如Ken White所述),如果车辆包含空间,则也必须对其进行处理
type
EMySplitError = class(Exception);
procedure SplitVehicleAndLicense( s : String; var vehicle,license : String);
var
p : Integer;
begin
vehicle := '';
license := '';
p := Pos('-',s);
if (p = 0) then
begin // No split delimiter
p := Pos(' ',s);
if (p > 0) then
begin
vehicle := Trim(Copy(s,1,p-1));
license := Trim(Copy(s,p+1,Length(s)));
end
else
Raise EMySplitError.CreateFmt('Not a valid vehicle/license name:%s',[s]);
end
else
begin
vehicle := Trim(Copy( s,1,p-1));
license := Trim(Copy( s,p+1,Length(s)));
end;
// Trim spaces in license
repeat
p := Pos(' ',license);
if (p <> 0) then Delete(license,p,1);
until (p = 0);
end;
类型
emysplieror=类(异常);
过程拆分车辆许可证(s:String;var车辆,许可证:String);
变量
p:整数;
开始
车辆:='';
许可证:='';
p:=Pos('-',s);
如果(p=0),则
开始//无分割分隔符
p:=位置('',s);
如果(p>0),则
开始
车辆:=配平(副本(s,1,p-1));
许可证:=修剪(副本,p+1,长度);
结束
其他的
提出emysplitror.CreateFmt('不是有效的车辆/许可证名称:%s',[s]);
结束
其他的
开始
车辆:=配平(副本(s,1,p-1));
许可证:=修剪(副本,p+1,长度);
结束;
//修剪许可证中的空格
重复
p:=位置('',许可证);
如果为(p 0),则删除(许可证,p,1);
直到(p=0);
结束;
前面有故障
如果该字段最初是由用户以您现在看到的形式输入的,那么我们可以假设没有验证,原始程序只会存储用户输入的任何内容。如果是这样的话,你就不能得到100%的准确率:人类总是会故意或无意地犯错误。预计会出现此类人为错误:
- 缺少字段(即:仅注册,无车辆信息-或相反)
- 无意义的词语重复(例如:“Ford K-TU 69 YUP”)
- 丢失的字母、重复的字母、多余的垃圾字母。示例:“对于K-T69YUP”
- 字段顺序错误
- 其他你做梦也想不到的小错误
- 普通的垃圾,连人都看不懂
- 查看您拥有的数据,这些数据尚未自动修复。找出一条明确适用于大量记录的规则
- 应用明确的规则
- 重复此操作,直到只剩下几条记录。这些应该用手来固定,因为它们抵制所有应用的自动方法
(.*?)(\ {1,3}-\ {1,3})?(\b[A-Z]{2}\ {0,2}[0-9]{2}\ {0,3}[A-Z]{3}\b)
如果您以前从未使用过正则表达式,那么单个表达式看起来很难理解,但实际上非常简单。这不是一个reg-ex问题,所以我不打算透露任何细节。我宁愿解释一下我是如何想出这个主意的
首先,如果文本中包含车辆登记号码,那么这些号码的格式将非常严格:它们很容易匹配。根据您的示例,我假设所有注册号的形式如下:
LLNNLLL
其中“L”是字母,“N”是数字。我的正则表达式对它的解释很严格:它只需要两个大写字母,后跟少量空格(或没有空格),后跟两个数字,后跟少量空格(或没有空格),最后后跟3个大写字母。正则表达式中处理这一问题的部分是:
[A-Z]{2}\ {0,2}[0-9]{2}\ {0,3}[A-Z]{3}
正则表达式的其余部分确保注册号没有嵌入到其他单词中,处理将文本分组到捕获组的问题,并为VehicleModel创建一个“惰性捕获组”
如果我自己实现这个,我可能会编写一个“master”函数和一些更简单的“case”函数,每个函数处理用户输入中的一种变化。例如:
// This function does a validation of the extracted data. For example it validates the
// Registration number, using other, more precise criteria. The parameters are VAR so the
// function may normalize the results.
function ResultsAreValid(var Make, Registration:string): Boolean;
begin
Result := True; // Only you know what your data looks like and how it can be validated.
end;
// This is a case function that deals with a very rigid interpretation of user data
function VeryStrictInterpretation(const Text:string; out Make, Registration: string): Boolean;
var TestMake, TestReg: string;
// regex engine ...
begin
Result := False;
if (your condition) then
if ResultsAreValid(TestMake, TestReg) then
begin
Make := TestMake;
Registration := TestReg;
Result := True;
end;
end;
// Master function calling many different implementations that each deal with all sorts
// of variations of input. The most strict function should be first:
function MasterTest(const Text:string; out Make, Registration: string): Boolean;
begin
Result := VeryStrictInterpretation(Text, Make, Registration);
if not Result then Result := SomeOtherImplementation(Text, Make, Registration);
if not Result then Result := ThirdInterpretation(Text, Make, Registration);
end;
这里的想法是尝试制作多个简单的程序,每个程序以明确的方式理解一种输入;确保每一步都不会出现误报!最后,别忘了,人类应该处理最后几个案例,所以不要指望解决所有问题。要做到这一点,您需要一个分隔字符串的独特分隔符。只有在数据本身不包含该分隔符的情况下,或者在所有字符串上都是唯一的情况下,该分隔符不包含多次。考试中