Validate phone number with Symfony - regex

I want to validate the phone nummer in a form. I would like to check so number and the "(" and ")" char are valid only. So user can fill in +31(0)600000000. The +31 is already preset in the form. The number only is possible with the code below, only how to add the two chars?
Or is there a standaard better way to validate phone number?
#Assert\Length(min = 8, max = 20, minMessage = "min_lenght", maxMessage = "max_lenght")
#Assert\Regex(pattern="/^[0-9]*$/", message="number_only")

If you need a good and robust validator for numbers, with advanced options to valudate, I will advice to use google lib https://github.com/googlei18n/libphonenumber, there is existed symfony2 bundle https://github.com/misd-service-development/phone-number-bundle and you can see there is a assert annotation:
use Misd\PhoneNumberBundle\Validator\Constraints\PhoneNumber as AssertPhoneNumber;
/**
* #AssertPhoneNumber
*/
private $phoneNumber;

The regex you need is:
/^\(0\)[0-9]*$
or for the entire number
/^\+31\(0\)[0-9]*$
You can test and play around with your regex here (it also includes auto-generated explanations):
https://www.regex101.com/r/gD0hE5/1

Related

What is a valid AWSPhone? What test values can be used?

The docs say:
The AWSPhone scalar type represents a valid Phone Number. Phone numbers are serialized and deserialized as Strings. Phone numbers provided may be whitespace delimited or hyphenated. The number can specify a country code at the beginning but this is not required.
What determines whether a given string is a valid AWSPhone? In addition, is there any safe way to generate (possibly a large number of) AWSPhone test values that are guaranteed to be valid but assuredly are not in-use phone numbers?
TLDR: You cannot tell the exact rules how the type AWSPhone is validated in AppSync. However, if a value passes the test of the regular expression /^\+?\d[\d\s-]+$/ or validation by libphonenumber-js, then it is likely to be accepted by AppSync.
In the latest AppSync Developer Guide (Oct 6, 2021 UTC), the description was updated to:
A phone number. This value is stored as a string. Phone numbers can contain either spaces or hyphens to separate digit groups. Phone numbers without a country code are assumed to be US/North American numbers adhering to the North American Numbering Plan (NANP).
This doesn't really tell exactly what AppSync expects. E.g. Must country code include + as prefix?
From AWS's public repositories on GitHub, there are hints:
amplify-js datastore util method for frontend validation:
export const isAWSPhone = (val: string): boolean => {
return !!/^\+?\d[\d\s-]+$/.exec(val);
};
amplify-appsync-simulator for amplify CLI mock features:
//...
import { isValidNumber } from 'libphonenumber-js';
//...
const phoneValidator = (ast, options) => {
//...
let isValid = isValidNumber(value, country);
//...
}
Therefore, a value is likely to be accepted by AppSync if it passes the above regex test and validation by libphonenumber-js (or libphonenumber, assuming they work equivalently).
I would have a look at the popular google library for handling phone numbers
https://github.com/google/libphonenumber
libphonenumber-js finds both 5555551212 and 555-555-1212 as invalid. What I have read is area code 555 is not a valid area code. So it would be the ideal number to generate known invalid test phone numbers, as well as a perfect phone number area code to be a known invalid initializer. But alas, dynamodb declares it as invalid.

How to get the most accurate term in regex?

I have an angular app using the mongodb sdk for js.
I would like to suggest some words on a input field for the user from my words collection, so I did:
getSuggestions(term: string) {
var regex = new stitch.BSON.BSONRegExp('^' +term , 'i');
return from(this.words.find({ 'Noun': { $regex: regex } }).execute());
}
The problem is that if the user type for example Bie, the query returns a lot of documents but the most accurated are the last ones, for example Bier, first it returns the bigger words, like Bieberbach'sche Vermutung. How can I deal to return the closests documents first?
A regular-expression is probably not enough to do what you are intending to do here. They can only do what they're meant to do – match a string. They might be used to give you a candidate entry to present to the user, but can't judge or weigh them. You're going to have to devise that logic yourself.

Best way to compare phone numbers using Regex

I have two databases that store phone numbers. The first one stores them with a country code in the format 15555555555 (a US number), and the other can store them in many different formats (ex. (555) 555-5555, 5555555555, 555-555-5555, 555-5555, etc.). When a phone number unsubscribes in one database, I need to unsubscribe all references to it in the other database.
What is the best way to find all instances of phone numbers in the second database that match the number in the first database? I'm using the entity framework. My code right now looks like this:
using (FusionEntities db = new FusionEntities())
{
var communications = db.Communications.Where(x => x.ValueType == 105);
foreach (var com in communications)
{
string sRegexCompare = Regex.Replace(com.Value, "[^0-9]", "");
if (sMobileNumber.Contains(sRegexCompare) && sRegexCompare.Length > 6)
{
var contact = db.Contacts.Where(x => x.ContactID == com.ContactID).FirstOrDefault();
contact.SMSOptOutDate = DateTime.Now;
}
}
}
Right now, my comparison checks to see if the first database contains at least 7 digits from the second database after all non-numeric characters are removed.
Ideally, I want to be able to apply the regex formatting to the point in the code where I get the data from the database. Initially I tried this, but I can't use replace in a LINQ query:
var communications = db.Communications.Where(x => x.ValueType == 105 && sMobileNumber.Contains(Regex.Replace(x.Value, "[^0-9]", "")));
Comparing phone numbers is a bit beyond the capability of regex by design. As you've discovered there are many ways to represent a phone number with and without things like area codes and formatting. Regex is for pattern matching so as you've found using the regex to strip out all formatting and then comparing strings is doable but putting logic into regex which is not what it's for.
I would suggest the first and biggest thing to do is sort out the representation of phone numbers. Since you have database access you might want to look at creating a new field or table to represent a phone number object. Then put your comparison logic in the model.
Yes it's more work but it keeps the code more understandable going forward and helps cleanup crap data.

Regular expression for checking postal address field value

I am looking for a regular-expression which can be used to check a postal address field value, with minimum length of 10, containing numbers, and characters as well:
Currently I use this expression:
`\\[a-zA-Z]|\d|.|\s{10,}`
The environment is:
lotus xpages, and the regular expression is stored in properties file within the application design.
<xp:inputText id="address" dojoType="dijit.form.ValidationTextBox" value="#{complaintDocument.address}">
<xp:this.dojoAttributes>
<xp:dojoAttribute name="promptMessage">
<xp:this.value><![CDATA[${javascript:clientData['address']}]]></xp:this.value>
</xp:dojoAttribute>
<xp:dojoAttribute name="placeHolder">
<xp:this.value><![CDATA[${javascript:common['textValueMinimumTenCharacters']}]]></xp:this.value>
</xp:dojoAttribute>
<xp:dojoAttribute name="trim" value="true">
</xp:dojoAttribute>
<xp:dojoAttribute name="regExp">
<xp:this.value><![CDATA[#{javascript:regExp['minimumTenCharacters']}]]></xp:this.value>
</xp:dojoAttribute>
</xp:this.dojoAttributes>
</xp:inputText>
Is there any wat to make the regular expression for this purpose more simple?
I dont thinkt that your regex can be any simpler. Maybe you could use
.{10} > any character, max 10 length
If you want to check if a zipcode is valid you can make a java class that is used to check if the zipcode that was filled in is correct. This class can be a stored in the application scope
<faces-config>
<managed-bean-name>
yourzipcodeclass</managed-bean-name>
<managed-bean-scope>
application</managed-bean-scope>
<managed-bean-class>yourclass</managed-bean-class>
</faces-config>
</faces-config>
Anyways When you want to check if a value is a valid zipcode you should add a method to this class isValidZipCode(String code, String country)
in this method you check depending on the country you have given if the zipcode is correct. How you check it is up to you. You can use a regex for every country or you can use a webservice, or a lookup in a database etc.
You can use this method in a custom validator.

Validating a Salesforce Id

Is there a way to validate a Salesforce ID, maybe using RegEx? They are normally 15 chars or 18 chars but do they follow a pattern that we can use to check that it's a valid id.
There are two levels of validating salesforce id:
check format using regular expression [a-zA-Z0-9]{15}|[a-zA-Z0-9]{18}
for 18-characted ids you can check the the 3-character checksum:
Code examples provided in comments:
C#
Go
Javascript
Ruby
Something like this should work:
[a-zA-Z0-9]{15,18}
It was suggested that this may be more correct because it prevents Ids with lengths of 16 and 17 characters to be rejected, also we try to match against 18 char length first with 15 length as a fallback:
[a-zA-Z0-9]{18}|[a-zA-Z0-9]{15}
Just use instanceOf to check if the string is an instance of Id.
String s = '1234';
if (s instanceOf Id) System.debug('valid id');
else System.debug('invalid id');
The easiest way I've come across, is to create a new ID variable and assign a String to it.
ID MyTestID = null;
try {
MyTestID = MyTestString; }
catch(Exception ex) { }
If MyTestID is null after trying to assign it, the ID was invalid.
This regex has given me the optimal results so far.
\b[a-z0-9]\w{4}0\w{12}|[a-z0-9]\w{4}0\w{9}\b
You can also check for 15 chars, and then add an extra 3 chars optional, with an expression similar to:
^[a-z0-9]{15}(?:[a-z0-9]{3})?$
on i mode, or not:
^[A-Za-z0-9]{15}(?:[A-Za-z0-9]{3})?$
Demo
If you wish to simplify/modify/explore the expression, it's been explained on the top right panel of regex101.com. If you'd like, you can also watch in this link, how it would match against some sample inputs.
RegEx Circuit
jex.im visualizes regular expressions:
Javascript: /^(?=.*?\d)(?=.*?[a-z])[a-z\d]{18}$/i
These were the Salesforce Id validation requirements for me.
18 characters only
At least one digit
At least one alphabet
Case insensitive
Test cases
Should fail
1
a
1234
abgcde
1234aDcde
12345678901234567*
123456789012345678
abcDefghijabcdefgh
Should pass
1234567890abcDeFgh
1234abcd1234abcd12
abcd1234abcd1234ab
1abcDefhijabcdefgf
abcDefghijabcdefg1
12345678901234567a
a12345678901234567
For understanding the regex, please refer this thread
The regex provided by Daniel Sokolowski works perfectly to verify if the id is in the correct format.
If you want to verify if an id corresponds to an actual record in the database, you'll need to first find the object type from the first three characters (commonly known as prefix) and then query the object type:
boolean isValidAndExists(String key) {
Map<String, Schema.SObjectType> objTypes = Schema.getGlobalDescribe();
for (Schema.SObjectType objType : objTypes.values()) {
Schema.DescribeSObjectResult objDesc = objType.getDescribe();
if (objDesc.getKeyPrefix() == key.substring(0,3)) {
String objName = objDesc.getName();
String query = 'SELECT Id FROM ' + objName + ' WHERE Id = \'' + key + '\'';
SObject[] objs = Database.query(query);
return !objs.isEmpty();
}
}
return false;
}
Be aware that Schema.getGlobalDescribe can be an expensive operation and degrade the performance of your application if you use that often.
If you need to check that often, I recommend creating a Custom Setting or Custom Metadata to store the relation between prefixes and object types.
Assuming you want to validate Ids in Apex, there are a few approaches discussed in the other answers. Here is an alternative, with notes on the various approaches.
The try-catch method (credit to #matt_k) certainly works, but some folks worry about overhead, especially if testing many Ids.
I used instanceof Id for a long time (credit to #melani_s), until I discovered that it sometimes gives the wrong answer (e.g., '481D0B74-41CF-47E9').
Multiple answers suggest regexen. As the accepted answer correctly points out (credit to #zacheusz), 18 character Ids are only valid if their checksums are correct, which means the regex solutions can be wrong. That answer also helpfully provides code in several languages to test Id checksums. But not in Apex.
I was going to implement the checksum code in Apex, but then I realized the Salesforce had already done the work, so instead I just convert 18 digit Ids to 15 digit Ids (via .to15() which uses the checksum to fix capitalization, as opposed to truncating the string) and then back to 18 digits to let SF do the checksum calc, then I compare the original checksum and the new one. This is my method:
static Pattern ID_REGEX = Pattern.compile('[a-zA-Z0-9]{15}(?:[A-Z0-5]{3})?');
/**
* #description Determines if a string is a valid SalesforceId. Confirms checksum of 18 digit Ids.
* Works for cases where `x instanceof id` returns the wrong answer, like '481D0B74-41CF-47E9'.
* Does NOT check for the existence of a record with the given Id.
* #param s a string to validate
*
* #return true if the string `s` is a valid Salesforce Id.
*/
public static Boolean isValidId(String s) {
Matcher m = ID_REGEX.matcher(s);
if (m.matches() == false) return false; // if it doesn't match the regex it cannot be valid
if (s.length() == 15) return true; // if 15 char string matches the regex, assume it must be valid
String check = (Id)((Id)s).to15(); // Convert to 15 char Id, then to Id and back to string, giving correct 18-char Id
return s.right(3) == check.right(3); // if 18 char string matches the regex, valid if checksum correct
}
Additionally checking getSObjectType() != null would be perfect if we are dealing with Salesforce records
public static boolean isRecordId(string recordId){
try{
return string.isNotBlank(recordId) && ((Id)recordId.trim()).getSObjectType() != null;
}catch(Exception ex){
return false;
}
}