Quick.RegEx.Utils.pas 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. { ***************************************************************************
  2. Copyright (c) 2016-2021 Kike Pérez
  3. Unit : Quick.RegEx.Utils
  4. Description : Common string validations
  5. Author : Kike Pérez
  6. Version : 2.0
  7. Created : 07/04/2021
  8. Modified : 07/04/2021
  9. This file is part of QuickLib: https://github.com/exilon/QuickLib
  10. ***************************************************************************
  11. Licensed under the Apache License, Version 2.0 (the "License");
  12. you may not use this file except in compliance with the License.
  13. You may obtain a copy of the License at
  14. http://www.apache.org/licenses/LICENSE-2.0
  15. Unless required by applicable law or agreed to in writing, software
  16. distributed under the License is distributed on an "AS IS" BASIS,
  17. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18. See the License for the specific language governing permissions and
  19. limitations under the License.
  20. *************************************************************************** }
  21. unit Quick.RegEx.Utils;
  22. {$i QuickLib.inc}
  23. interface
  24. uses
  25. System.SysUtils,
  26. System.RegularExpressions;
  27. type
  28. TRegExUtils = class
  29. /// <summary> Validates if value is Integer or Float number </summary>
  30. class function IsNumber(const aValue : string) : Boolean;
  31. /// <summary> Validates if value is Integer number </summary>
  32. class function IsInteger(const aValue : string) : Boolean;
  33. /// <summary> Validates if value is Float number </summary>
  34. class function IsFloat(const aValue : string) : Boolean;
  35. /// <summary> Validates if value is alphanumeric with optional space char as valid char </summary>
  36. class function IsAlphanumeric(const aValue : string; aSpaceCharAsValid : Boolean = True) : Boolean;
  37. /// <summary> Validates email address </summary>
  38. class function IsValidEmail(const aEmail : string) : Boolean;
  39. /// <summary> Validates password complexity (Should have 1 lowercase letter, 1 uppercase letter, 1 number,
  40. /// 1 special character and be at least 8 characters long) </summary>
  41. class function IsPasswordComplex(const aPassword : string) : Boolean;
  42. /// <summary> Validate username (may include _ and – with min and max length restriction) </summary>
  43. class function IsValidUsername(const aUsername: string; aMinLength : Integer = 3; aMaxLength : Integer = 18): Boolean;
  44. // <summary> Validates Url with optional protocol </summary>
  45. class function IsValidUrl(const aUrl: string; aProtocolOptional : Boolean): Boolean;
  46. // <summary> Validates Ip v4 </summary>
  47. class function IsValidIpv4(const aIp : string) : Boolean;
  48. // <summary> Validates Ip v6 </summary>
  49. class function IsValidIpv6(const aIp : string) : Boolean;
  50. // <summary> Validates date format YYYMMdd with - or . or / </summary>
  51. class function IsValidDate_YYYYMMdd(const aDate : string) : Boolean;
  52. // <summary> Validates date format ddMMYYYY with - or . or / </summary>
  53. class function IsValidDate_ddMMYYY(const aDate : string) : Boolean;
  54. // <summary> Validates Httml tag </summary>
  55. class function IsValidHtmlTag(const aValue : string) : Boolean;
  56. // <summary> Validates for duplicates in a string </summary>
  57. class function HasDuplicates(const aValue : string) : Boolean;
  58. /// <summary> Validates international number with optional country code/extension </summary>
  59. class function IsValidPhoneNumber(const aPhoneNumber : string) : Boolean;
  60. /// <summary> Validates Path, filename and extension </summary>
  61. class function IsValidFilePath(const aFilePath : string) : Boolean;
  62. /// <summary> Validates Visa card number </summary>
  63. class function IsValidVisaCard(const aCardNumber : string) : Boolean;
  64. /// <summary> Validates Master Card number </summary>
  65. class function IsValidMasterCard(const aCardNumber : string) : Boolean;
  66. /// <summary> Validates American Express card number /summary>
  67. class function IsValidAmericanExpressCard(const aCardNumber : string) : Boolean;
  68. /// <summary> Validates Passport number</summary>
  69. class function IsValidPassport(const aPassport : string) : Boolean;
  70. /// <summary> Validates Spanish Documento Nacional de Identidad </summary>
  71. class function IsValidDNI_ES(const aDNI : string) : Boolean;
  72. /// <summary> Validates USA Social Security Number document </summary>
  73. class function IsValidSSN_US(const aSSN : string) : Boolean;
  74. end;
  75. implementation
  76. { TRegExUtils }
  77. class function TRegExUtils.IsNumber(const aValue: string): Boolean;
  78. begin
  79. Result := TRegEx.IsMatch(aValue,'^(-|)\d*(\.\d+)?$');
  80. end;
  81. class function TRegExUtils.IsFloat(const aValue: string): Boolean;
  82. begin
  83. Result := TRegEx.IsMatch(aValue,'^(-|)\d*\.\d+$');
  84. end;
  85. class function TRegExUtils.IsInteger(const aValue: string): Boolean;
  86. begin
  87. Result := TRegEx.IsMatch(aValue,'^\d+$');
  88. end;
  89. class function TRegExUtils.IsAlphanumeric(const aValue : string; aSpaceCharAsValid : Boolean) : Boolean;
  90. begin
  91. if aSpaceCharAsValid then Result := TRegEx.IsMatch(aValue,'^[a-zA-Z0-9 ]*$')
  92. else Result := TRegEx.IsMatch(aValue,'^[a-zA-Z0-9]*$');
  93. end;
  94. class function TRegExUtils.IsPasswordComplex(const aPassword : string) : Boolean;
  95. begin
  96. Result := TRegEx.IsMatch(aPassword,'(?=(.*[0-9]))(?=.*[\!@#$%^&*()\\[\]{}\-_+=~`|:;"''<>,./?])(?=.*[a-z])(?=(.*[A-Z]))(?=(.*)).{8,}');
  97. end;
  98. class function TRegExUtils.IsValidEmail(const aEmail: string): Boolean;
  99. begin
  100. Result := TRegEx.IsMatch(aEmail,'^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6})*$');
  101. end;
  102. class function TRegExUtils.IsValidFilePath(const aFilePath: string): Boolean;
  103. begin
  104. Result := TRegEx.IsMatch(aFilePath,'((\/|\\|\/\/|https?:\\\\|https?:\/\/)[a-z0-9_@\-^!#$%&+={}.\/\\\[\]]+)+\.[a-z]+$');
  105. end;
  106. class function TRegExUtils.IsValidUsername(const aUsername: string; aMinLength : Integer; aMaxLength : Integer): Boolean;
  107. begin
  108. Result := TRegEx.IsMatch(aUsername,Format('^[A-Za-z0-9_-]{%d,%d}$',[aMinLength,aMaxLength]));
  109. end;
  110. class function TRegExUtils.IsValidUrl(const aUrl: string; aProtocolOptional : Boolean): Boolean;
  111. begin
  112. if aProtocolOptional then Result := TRegEx.IsMatch(aUrl,'(https?:\/\/)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)')
  113. else Result := TRegEx.IsMatch(aUrl,'https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#()?&//=]*)');
  114. end;
  115. class function TRegExUtils.IsValidIpv4(const aIp: string): Boolean;
  116. begin
  117. Result := TRegEx.IsMatch(aIp,'^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$');
  118. end;
  119. class function TRegExUtils.IsValidIpv6(const aIp: string): Boolean;
  120. begin
  121. Result := TRegEx.IsMatch(aIp,'(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]'
  122. +'{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|'
  123. +'([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}'
  124. +'(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}'
  125. +'|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)'
  126. +'|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}'
  127. +'((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9])'
  128. +'{0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.)'
  129. +'{3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))');
  130. end;
  131. class function TRegExUtils.IsValidDate_ddMMYYY(const aDate: string): Boolean;
  132. begin
  133. Result := TRegEx.IsMatch(aDate,'^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)'
  134. + '(?:0?[13-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-'
  135. +'|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|'
  136. +'(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)'
  137. +'(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$');
  138. end;
  139. class function TRegExUtils.IsValidDate_YYYYMMdd(const aDate: string): Boolean;
  140. begin
  141. Result := TRegEx.IsMatch(aDate,'([12]\d{3}(\/|-|\.)(0[1-9]|1[0-2])(\/|-|\.)(0[1-9]|[12]\d|3[01]))');
  142. end;
  143. class function TRegExUtils.IsValidHtmlTag(const aValue: string): Boolean;
  144. begin
  145. Result := TRegEx.IsMatch(aValue,'<\/?[\w\s]*>|<.+[\W]>');
  146. end;
  147. class function TRegExUtils.HasDuplicates(const aValue: string): Boolean;
  148. begin
  149. Result := TRegEx.IsMatch(aValue,'(\b\w+\b)(?=.*\b\1\b)');
  150. end;
  151. class function TRegExUtils.IsValidPhoneNumber(const aPhoneNumber: string): Boolean;
  152. begin
  153. Result := TRegEx.IsMatch(aPhoneNumber,'^(?:(?:\(?(?:00|\+)([1-4]\d\d|[1-9]\d?)\)?)?[\-\.\ \\\/]?)?((?:\(?\d{1,}\)?[\-\.\ \\\/]?){0,})(?:[\-\.\ \\\/]?(?:#|ext\.?|extension|x)[\-\.\ \\\/]?(\d+))?$');
  154. end;
  155. class function TRegExUtils.IsValidVisaCard(const aCardNumber: string): Boolean;
  156. begin
  157. Result := TRegEx.IsMatch(aCardNumber,'^4[0-9]{12}(?:[0-9]{3})?$');
  158. end;
  159. class function TRegExUtils.IsValidMasterCard(const aCardNumber: string): Boolean;
  160. begin
  161. Result := TRegEx.IsMatch(aCardNumber,'^(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}$');
  162. end;
  163. class function TRegExUtils.IsValidAmericanExpressCard(const aCardNumber: string): Boolean;
  164. begin
  165. Result := TRegEx.IsMatch(aCardNumber,'^3[47][0-9]{13}$');
  166. end;
  167. class function TRegExUtils.IsValidPassport(const aPassport: string): Boolean;
  168. begin
  169. Result := TRegEx.IsMatch(aPassport,'^[A-PR-WY][1-9]\d\s?\d{4}[1-9]$');
  170. end;
  171. class function TRegExUtils.IsValidDNI_ES(const aDNI: string): Boolean;
  172. begin
  173. Result := TRegEx.IsMatch(aDNI,'((([X-Z])|([LM])){1}([-]?)((\d){7})([-]?)([A-Z]{1}))|((\d{8})([-]?)([A-Z]))');
  174. end;
  175. class function TRegExUtils.IsValidSSN_US(const aSSN: string): Boolean;
  176. begin
  177. Result := TRegEx.IsMatch(aSSN,'^((?!219-09-9999|078-05-1120)(?!666|000|9\d{2})\d{3}-(?!00)\d{2}-(?!0{4})\d{4})|((?!219 09 9999|078 05 1120)(?!666|000|9\d{2})\d{3} (?!00)\d{2} (?!0{4})\d{4})|((?!219099999|078051120)(?!666|000|9\d{2})\d{3}(?!00)\d{2}(?!0{4})\d{4})$');
  178. end;
  179. end.