Skip to content

Instantly share code, notes, and snippets.

@rishabhmhjn
Last active March 2, 2022 02:04
Show Gist options
  • Save rishabhmhjn/8663966 to your computer and use it in GitHub Desktop.
Save rishabhmhjn/8663966 to your computer and use it in GitHub Desktop.
Regex to validate Android Package Name
var pattern = /^[a-z][a-z0-9_]*(\.[a-z0-9_]+)+[0-9a-z_]$/i;
[
"me.unfollowers.droid",
"me_.unfollowers.droid",
"me._unfollowers.droid",
"me.unfo11llowers.droid",
"me11.unfollowers.droid",
"m11e.unfollowers.droid",
"1me.unfollowers.droid",
"me.unfollowers23.droid",
"me.unfollowers.droid23d",
"me.unfollowers_.droid",
"me.unfollowers._droid",
"me.unfollowers_._droid",
"me.unfollowers.droid_",
"me.unfollowers.droid32",
"me.unfollowers.droid/",
"me:.unfollowers.droid",
":me.unfollowers.droid",
"me.unfollowers.dro;id",
"me.unfollowe^rs.droid",
"me.unfollowers.droid.",
"me.unfollowers..droid",
"me.unfollowers.droid._",
"me.unfollowers.11212",
"me.1.unfollowers.11212",
"me..unfollowers.11212",
"abc",
"abc.",
".abc"
].forEach(function(pkg) {
console.log('[' + (pattern.test(pkg) ? '✔' : '✘') + ']\t' + pkg);
});

Result

[✔] me.unfollowers.droid
[✔] me_.unfollowers.droid
[✔] me._unfollowers.droid
[✔] me.unfo11llowers.droid
[✔] me11.unfollowers.droid
[✔] m11e.unfollowers.droid
[✗] 1me.unfollowers.droid
[✔] me.unfollowers23.droid
[✔] me.unfollowers.droid23d
[✔] me.unfollowers_.droid
[✔] me.unfollowers._droid
[✔] me.unfollowers_._droid
[✔] me.unfollowers.droid_
[✔] me.unfollowers.droid32
[✗] me.unfollowers.droid/
[✗] me:.unfollowers.droid
[✗] :me.unfollowers.droid
[✗] me.unfollowers.dro;id
[✗] me.unfollowe^rs.droid
[✗] me.unfollowers.droid.
[✗] me.unfollowers..droid
[✗] me.unfollowers.droid._
[✔] me.unfollowers.11212
[✔] me.1.unfollowers.11212
[✗] me..unfollowers.11212
[✗] abc
[✗] abc.
[✗] .abc
@eighthave
Copy link

eighthave commented Sep 7, 2018

If you want to be truly pedantic about it, then all of the Java Package Name rules need to be included, like no Java reserved words allowed. It makes for an epicly large regex:

https://stackoverflow.com/a/39331217

(?!^abstract$|^abstract\..*|.*\.abstract\..*|.*\.abstract$|^assert$|^assert\..*|.*\.assert\..*|.*\.assert$|^boolean$|^boolean\..*|.*\.boolean\..*|.*\.boolean$|^break$|^break\..*|.*\.break\..*|.*\.break$|^byte$|^byte\..*|.*\.byte\..*|.*\.byte$|^case$|^case\..*|.*\.case\..*|.*\.case$|^catch$|^catch\..*|.*\.catch\..*|.*\.catch$|^char$|^char\..*|.*\.char\..*|.*\.char$|^class$|^class\..*|.*\.class\..*|.*\.class$|^const$|^const\..*|.*\.const\..*|.*\.const$|^continue$|^continue\..*|.*\.continue\..*|.*\.continue$|^default$|^default\..*|.*\.default\..*|.*\.default$|^do$|^do\..*|.*\.do\..*|.*\.do$|^double$|^double\..*|.*\.double\..*|.*\.double$|^else$|^else\..*|.*\.else\..*|.*\.else$|^enum$|^enum\..*|.*\.enum\..*|.*\.enum$|^extends$|^extends\..*|.*\.extends\..*|.*\.extends$|^final$|^final\..*|.*\.final\..*|.*\.final$|^finally$|^finally\..*|.*\.finally\..*|.*\.finally$|^float$|^float\..*|.*\.float\..*|.*\.float$|^for$|^for\..*|.*\.for\..*|.*\.for$|^goto$|^goto\..*|.*\.goto\..*|.*\.goto$|^if$|^if\..*|.*\.if\..*|.*\.if$|^implements$|^implements\..*|.*\.implements\..*|.*\.implements$|^import$|^import\..*|.*\.import\..*|.*\.import$|^instanceof$|^instanceof\..*|.*\.instanceof\..*|.*\.instanceof$|^int$|^int\..*|.*\.int\..*|.*\.int$|^interface$|^interface\..*|.*\.interface\..*|.*\.interface$|^long$|^long\..*|.*\.long\..*|.*\.long$|^native$|^native\..*|.*\.native\..*|.*\.native$|^new$|^new\..*|.*\.new\..*|.*\.new$|^package$|^package\..*|.*\.package\..*|.*\.package$|^private$|^private\..*|.*\.private\..*|.*\.private$|^protected$|^protected\..*|.*\.protected\..*|.*\.protected$|^public$|^public\..*|.*\.public\..*|.*\.public$|^return$|^return\..*|.*\.return\..*|.*\.return$|^short$|^short\..*|.*\.short\..*|.*\.short$|^static$|^static\..*|.*\.static\..*|.*\.static$|^strictfp$|^strictfp\..*|.*\.strictfp\..*|.*\.strictfp$|^super$|^super\..*|.*\.super\..*|.*\.super$|^switch$|^switch\..*|.*\.switch\..*|.*\.switch$|^synchronized$|^synchronized\..*|.*\.synchronized\..*|.*\.synchronized$|^this$|^this\..*|.*\.this\..*|.*\.this$|^throw$|^throw\..*|.*\.throw\..*|.*\.throw$|^throws$|^throws\..*|.*\.throws\..*|.*\.throws$|^transient$|^transient\..*|.*\.transient\..*|.*\.transient$|^try$|^try\..*|.*\.try\..*|.*\.try$|^void$|^void\..*|.*\.void\..*|.*\.void$|^volatile$|^volatile\..*|.*\.volatile\..*|.*\.volatile$|^while$|^while\..*|.*\.while\..*|.*\.while$)(^(?:[a-z_]+(?:\d*[a-zA-Z_]*)*)(?:\.[a-z_]+(?:\d*[a-zA-Z_]*)*)*$)

@a90120411
Copy link

This will include some invalid Application IDs. There must be at least two segment separated by ., and the first letter of each segment cannot be upper case or a number. https://developer.android.com/studio/build/application-id Something like this gets much closer to complete support:

^(?:[a-z_]+(?:\\d*[a-zA-Z_]*)*)(?:\\.[a-z_]+(?:\\d*[a-zA-Z_]*)*)*$

It verifies that "aaa" failed.

I'm changed it to

^(?:[a-zA-Z]+(?:\d*[a-zA-Z_]*)*)(?:\.[a-zA-Z]+(?:\d*[a-zA-Z_]*)*)+$

package name rules
A full Java-language-style package name for the Android app. The name may contain uppercase or lowercase letters ('A' through 'Z'), numbers, and underscores ('_'). However, individual package name parts may only start with letters.

application ID rules
And although the application ID looks like a traditional Java package name, the naming rules for the application ID are a bit more restrictive:
It must have at least two segments (one or more dots).
Each segment must start with a letter.
All characters must be alphanumeric or an underscore [a-zA-Z0-9_].

https://developer.android.com/guide/topics/manifest/manifest-element
https://developer.android.com/studio/build/application-id

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment