正则表达式匹配 Android 包名

7

如何检查一个字符串是否是合法的Android包名?

5个回答

16

AndroidManifest文档中对包属性描述了有效的Android软件包名称:

名称应该是唯一的。名称可以包含大写或小写字母('A'到'Z'),数字和下划线('_')。但是,单个包名称部分只能以字母开头。

参见: https://developer.android.com/guide/topics/manifest/manifest-element.html#package


以下正则表达式将匹配一个有效的Android软件包名称:

^([A-Za-z]{1}[A-Za-z\d_]*\.)+[A-Za-z][A-Za-z\d_]*$

示例用法:

String regex = "^([A-Za-z]{1}[A-Za-z\\d_]*\\.)+[A-Za-z][A-Za-z\\d_]*$";
List<PackageInfo> packages = context.getPackageManager().getInstalledPackages(0);
for (PackageInfo packageInfo : packages) {
  if (packageInfo.packageName.matches(regex)) {
    // valid package name, of course.
  }
}

有关正则表达式的详细解释,请参见:https://regex101.com/r/EAod0W/1


这里捕获的不仅仅是A-Z。我认为包名不能是Åęø.ßlah - OneCricketeer
@cricket_007 你说得对。然而,当我之前测试时,我发现其他Unicode字母也是有效的。我需要进行更多的测试。谢谢。 - Jared Rummler
3
如果我没错的话,上面的正则表达式将会不合法地接受一个字符串"test1"。根据官方的Android规则,有效的包名必须至少有两个部分。我建议改进为:^([A-Za-z]{1}[A-Za-z\d_].)+[A-Za-z][A-Za-z\d_]$ - Eitan Schwartz
1
@EitanSchwartz 很好的发现。已更新答案。谢谢。 - Jared Rummler
2
@AniketSuryavanshi 在 Android 包名中不允许使用连字符。 - Jared Rummler
显示剩余2条评论

2
根据 @skeeve 的评论,您可以在 [a-z0-9_] 的位置使用 \w。
完整的正则表达式:

/^[a-z]\w*(\.[a-z]\w*)+$/i

解释:

i

全局模式标记,用于不区分大小写(忽略 [a-zA-Z] 的大小写)。

^

在一行开头确定位置:

[a-z]

匹配一个单个字符,范围在a(索引97)和z(索引122)之间(不区分大小写)

\w*

\w匹配任何单词字符(等同于[a-zA-Z0-9_])
*量词匹配零次或多次,尽可能多地匹配。

(.[a-z]\w*)+

括号定义一个组
“\.” 匹配字符"."(不区分大小写)
"[a-z]" 见上文
"\w*" 见上文

+

量词匹配一次到无限次,尽可能多地匹配。

$

在一行的末尾添加位置。

https://regex101.com/


1
我使用了这个正则表达式,并且根据 Android 应用 ID 官方文件进行了测试。
  • 它必须至少有两个部分(一个或多个点)。每个部分必须以字母开头。所有字符必须是字母数字或者下划线 [a-zA-Z0-9_]。
String regex = "^(?:[a-zA-Z]+(?:\d*[a-zA-Z_]*)*)(?:\.[a-zA-Z]+(?:\d*[a-zA-Z_]*)*)+$" ;

这个正则表达式显然容易受到某些正则表达式dos攻击,我是完全意外地发现我的应用程序冻结了。例如,对此进行测试会导致挂起:com.aliucord.guhhhhhhhhhhfhuhhhhhhhhhhhhhhhh4343hh$ - Diamond

0

从Android开发文档中,应用程序ID的命名规则如下:

  • 它必须至少有两个段(一个或多个点)。
  • 每个段必须以字母开头。
  • 所有字符必须是字母数字或下划线[a-zA-Z0-9_]。

这是这些规则的正则表达式:

/^[a-z][a-z0-9_](.[a-z][a-z0-9_])+$/i


3
描述是正确的,但正则表达式不正确。我相信应该是: ^[a-z][a-z0-9_](.[a-z][a-z0-9_])+$/i - skeeve

0

https://github.com/JetBrains/android/blob/7545bd83b798aebabef687a6be2fc763800d8d94/android/src/org/jetbrains/android/util/AndroidUtils.java#L727

以下代码未检查包名中不允许使用的Java关键字,例如break.app<<不是有效的包名。
请查看上面链接获取完整代码。
// This method is a copy of android.content.pm.PackageParser#validateName with the
  // error messages tweaked
  //Returns null if valid package name
  @Nullable
  private static String validateName(String name) {
    final int N = name.length();
    boolean hasSep = false;
    boolean front = true;
    for (int i=0; i<N; i++) {
      final char c = name.charAt(i);
      if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
        front = false;
        continue;
      }
      if ((c >= '0' && c <= '9') || c == '_') {
        if (!front) {
          continue;
        } else {
          if (c == '_') {
            return "The character '_' cannot be the first character in a package segment";
          } else {
            return "A digit cannot be the first character in a package segment";
          }
        }
      }
      if (c == '.') {
        hasSep = true;
        front = true;
        continue;
      }
      return "The character '" + c + "' is not allowed in Android application package names";
    }
    return hasSep ? null : "The package must have at least one '.' separator";
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接