{ *************************************************************************** Copyright (c) 2016-2021 Kike Pérez Unit : Quick.RegEx.Utils Description : Common string validations Author : Kike Pérez Version : 2.0 Created : 07/04/2021 Modified : 07/04/2021 This file is part of QuickLib: https://github.com/exilon/QuickLib *************************************************************************** Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. *************************************************************************** } unit Quick.RegEx.Utils; {$i QuickLib.inc} interface uses System.SysUtils, System.RegularExpressions; type TRegExUtils = class /// Validates if value is Integer or Float number class function IsNumber(const aValue : string) : Boolean; /// Validates if value is Integer number class function IsInteger(const aValue : string) : Boolean; /// Validates if value is Float number class function IsFloat(const aValue : string) : Boolean; /// Validates if value is alphanumeric with optional space char as valid char class function IsAlphanumeric(const aValue : string; aSpaceCharAsValid : Boolean = True) : Boolean; /// Validates email address class function IsValidEmail(const aEmail : string) : Boolean; /// Validates password complexity (Should have 1 lowercase letter, 1 uppercase letter, 1 number, /// 1 special character and be at least 8 characters long) class function IsPasswordComplex(const aPassword : string) : Boolean; /// Validate username (may include _ and – with min and max length restriction) class function IsValidUsername(const aUsername: string; aMinLength : Integer = 3; aMaxLength : Integer = 18): Boolean; // Validates Url with optional protocol class function IsValidUrl(const aUrl: string; aProtocolOptional : Boolean): Boolean; // Validates Ip v4 class function IsValidIpv4(const aIp : string) : Boolean; // Validates Ip v6 class function IsValidIpv6(const aIp : string) : Boolean; // Validates date format YYYMMdd with - or . or / class function IsValidDate_YYYYMMdd(const aDate : string) : Boolean; // Validates date format ddMMYYYY with - or . or / class function IsValidDate_ddMMYYY(const aDate : string) : Boolean; // Validates Httml tag class function IsValidHtmlTag(const aValue : string) : Boolean; // Validates for duplicates in a string class function HasDuplicates(const aValue : string) : Boolean; /// Validates international number with optional country code/extension class function IsValidPhoneNumber(const aPhoneNumber : string) : Boolean; /// Validates Path, filename and extension class function IsValidFilePath(const aFilePath : string) : Boolean; /// Validates Visa card number class function IsValidVisaCard(const aCardNumber : string) : Boolean; /// Validates Master Card number class function IsValidMasterCard(const aCardNumber : string) : Boolean; /// Validates American Express card number /summary> class function IsValidAmericanExpressCard(const aCardNumber : string) : Boolean; /// Validates Passport number class function IsValidPassport(const aPassport : string) : Boolean; /// Validates Spanish Documento Nacional de Identidad class function IsValidDNI_ES(const aDNI : string) : Boolean; /// Validates USA Social Security Number document class function IsValidSSN_US(const aSSN : string) : Boolean; end; implementation { TRegExUtils } class function TRegExUtils.IsNumber(const aValue: string): Boolean; begin Result := TRegEx.IsMatch(aValue,'^(-|)\d*(\.\d+)?$'); end; class function TRegExUtils.IsFloat(const aValue: string): Boolean; begin Result := TRegEx.IsMatch(aValue,'^(-|)\d*\.\d+$'); end; class function TRegExUtils.IsInteger(const aValue: string): Boolean; begin Result := TRegEx.IsMatch(aValue,'^\d+$'); end; class function TRegExUtils.IsAlphanumeric(const aValue : string; aSpaceCharAsValid : Boolean) : Boolean; begin if aSpaceCharAsValid then Result := TRegEx.IsMatch(aValue,'^[a-zA-Z0-9 ]*$') else Result := TRegEx.IsMatch(aValue,'^[a-zA-Z0-9]*$'); end; class function TRegExUtils.IsPasswordComplex(const aPassword : string) : Boolean; begin Result := TRegEx.IsMatch(aPassword,'(?=(.*[0-9]))(?=.*[\!@#$%^&*()\\[\]{}\-_+=~`|:;"''<>,./?])(?=.*[a-z])(?=(.*[A-Z]))(?=(.*)).{8,}'); end; class function TRegExUtils.IsValidEmail(const aEmail: string): Boolean; begin Result := TRegEx.IsMatch(aEmail,'^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6})*$'); end; class function TRegExUtils.IsValidFilePath(const aFilePath: string): Boolean; begin Result := TRegEx.IsMatch(aFilePath,'((\/|\\|\/\/|https?:\\\\|https?:\/\/)[a-z0-9_@\-^!#$%&+={}.\/\\\[\]]+)+\.[a-z]+$'); end; class function TRegExUtils.IsValidUsername(const aUsername: string; aMinLength : Integer; aMaxLength : Integer): Boolean; begin Result := TRegEx.IsMatch(aUsername,Format('^[A-Za-z0-9_-]{%d,%d}$',[aMinLength,aMaxLength])); end; class function TRegExUtils.IsValidUrl(const aUrl: string; aProtocolOptional : Boolean): Boolean; begin if aProtocolOptional then Result := TRegEx.IsMatch(aUrl,'(https?:\/\/)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)') else Result := TRegEx.IsMatch(aUrl,'https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#()?&//=]*)'); end; class function TRegExUtils.IsValidIpv4(const aIp: string): Boolean; begin 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])$'); end; class function TRegExUtils.IsValidIpv6(const aIp: string): Boolean; begin 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]' +'{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}|' +'([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}' +'(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}' +'|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)' +'|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}' +'((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])' +'{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])\.)' +'{3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))'); end; class function TRegExUtils.IsValidDate_ddMMYYY(const aDate: string): Boolean; begin Result := TRegEx.IsMatch(aDate,'^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)' + '(?:0?[13-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-' +'|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|' +'(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)' +'(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$'); end; class function TRegExUtils.IsValidDate_YYYYMMdd(const aDate: string): Boolean; begin Result := TRegEx.IsMatch(aDate,'([12]\d{3}(\/|-|\.)(0[1-9]|1[0-2])(\/|-|\.)(0[1-9]|[12]\d|3[01]))'); end; class function TRegExUtils.IsValidHtmlTag(const aValue: string): Boolean; begin Result := TRegEx.IsMatch(aValue,'<\/?[\w\s]*>|<.+[\W]>'); end; class function TRegExUtils.HasDuplicates(const aValue: string): Boolean; begin Result := TRegEx.IsMatch(aValue,'(\b\w+\b)(?=.*\b\1\b)'); end; class function TRegExUtils.IsValidPhoneNumber(const aPhoneNumber: string): Boolean; begin Result := TRegEx.IsMatch(aPhoneNumber,'^(?:(?:\(?(?:00|\+)([1-4]\d\d|[1-9]\d?)\)?)?[\-\.\ \\\/]?)?((?:\(?\d{1,}\)?[\-\.\ \\\/]?){0,})(?:[\-\.\ \\\/]?(?:#|ext\.?|extension|x)[\-\.\ \\\/]?(\d+))?$'); end; class function TRegExUtils.IsValidVisaCard(const aCardNumber: string): Boolean; begin Result := TRegEx.IsMatch(aCardNumber,'^4[0-9]{12}(?:[0-9]{3})?$'); end; class function TRegExUtils.IsValidMasterCard(const aCardNumber: string): Boolean; begin 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}$'); end; class function TRegExUtils.IsValidAmericanExpressCard(const aCardNumber: string): Boolean; begin Result := TRegEx.IsMatch(aCardNumber,'^3[47][0-9]{13}$'); end; class function TRegExUtils.IsValidPassport(const aPassport: string): Boolean; begin Result := TRegEx.IsMatch(aPassport,'^[A-PR-WY][1-9]\d\s?\d{4}[1-9]$'); end; class function TRegExUtils.IsValidDNI_ES(const aDNI: string): Boolean; begin Result := TRegEx.IsMatch(aDNI,'((([X-Z])|([LM])){1}([-]?)((\d){7})([-]?)([A-Z]{1}))|((\d{8})([-]?)([A-Z]))'); end; class function TRegExUtils.IsValidSSN_US(const aSSN: string): Boolean; begin 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})$'); end; end.