在不使用 Regex 的情况下,下划线、点和破折号后面必须始终跟一个或多个字母数字字符
An underscore, a dot and a dash must always be followed by one or more alphanumeric characters without using Regex
我正在做一项不使用 Regex 验证电子邮件的学校作业。本练习的前提是学习方法并练习我们的批判性思维。我知道代码可以减少到更少的行数。
现在,我需要检查电子邮件前缀的所有条件('@'之前的字符):
- 至少包含一个字符。
- 它仅包含字母数字字符、下划线(‘_’)、句点(‘.’)和破折号(‘-’)。
- 下划线、句点或破折号后必须始终跟一个或多个字母数字字符。
- 第一个字符必须是字母数字。
有效前缀的示例是:“abc-d”、“abc.def”、“abc”、“abc_def”。
无效前缀的示例是:“abc-”、“abc..d”、“.abc”、“abc#def”。
我很难弄清楚第三个条件。到目前为止,我有这些满足其他条件的方法。
public static boolean isAlphanumeric(char c) {
return Character.isLetterOrDigit(c);
}
public static boolean isValidPrefixChar(char preChar) {
char[] prefixChar = new char[] {'-', '.', '_'};
for (int i = 0; i < prefixChar.length; i++) {
if (prefixChar[i] == preChar) {
return true;
} else if (isAlphanumeric(preChar)) {
return true;
}
}
return false;
}
public static boolean isValidPrefix(String emailPrefix) {
boolean result = false;
// To check if first character is alphanumeric
if (isAlphanumeric(emailPrefix.charAt(0)) && emailPrefix.length() > 1) {
for (int i = 0; i < emailPrefix.length(); i++) {
// If email prefix respects all conditions, change result to true
if (isValidPrefixChar(emailPrefix.charAt(i))) {
result = true;
} else {
result = false;
break;
}
}
}
return result;
}
让我们看看您的列表:
- 至少包含一个字符。
- 它仅包含字母数字字符、下划线(‘_’)、句点(‘.’)和破折号(‘-’)。
- 下划线、句点或破折号后必须始终跟一个或多个字母数字字符。
- 第一个字符必须是字母数字。
正如你所说,1、2、4 很简单。这就是我会做的。如果不正确,我的第一行将检查长度和 return false。然后我会遍历字符。在循环内;
- 设置布尔值 lastWasSpecial = false。
- 检查它是否为合法字符(条件 2)
- 如果索引 == 0,请检查它是否为字母数字(条件 4)
- 如果是特色菜之一:
- 如果设置了 lastWasSpecial,return false
- 设置 lastWasSpecial = true;
- 否则再次设置 lastWasSpecial = false
应该是大约 10 行 easily-readable 代码。
local-part
仅供参考,COMMERCIAL AT 符号 (@
) 之前的地址部分称为 local-part。
避免char
当遇到 BMP 之外的字符时,使用 char
的代码将会中断。作为 16 位值,char
不能表示大多数字符。
代码点
在处理单个字符时,请改用代码点。代码点是永久分配给 Unicode 中定义的 140,000 多个字符中的每一个的编号。
int[] codePoints = localPart.codePoints().toArray() ;
定义一个数组、列表或一组您可接受的标点字符。
int codePoint = "-".codePointAt( 0 ) ; // Annoying zero-based index counting.
要验证遇到的每个标点符号后跟一个 letter/digit,首先要确保标点符号不是最后一个字符。如果不是,则在数组中查找以下代码点。测试该代码点是否 is a letter or digit.
if( Character.isLetterOrDigit( codePoints[ i + 1 ] ) ) { … }
算法可以优化,但我尝试只更改一些行并使用相同的代码风格。我在评论里加了说明
public static boolean isAlphanumeric(char c) {
return Character.isLetterOrDigit(c);
}
public static boolean isValidPrefixChar(char preChar) {
char[] prefixChar = new char[]{'-', '.', '_'};
for (int i = 0; i < prefixChar.length; i++) {
if (prefixChar[i] == preChar) {
return true;
}
}
return false;
}
public static boolean isValidPrefix(String emailPrefix) {
boolean result = false;
// To check if first character is alphanumeric
if (isAlphanumeric(emailPrefix.charAt(0)) && emailPrefix.length() > 1) {
// this boolean is set to true when the next char has to be alphanumeric
boolean nextHasToBeAlphaNumeric = false;
// the for loop start from 1 because char 0 has been already checked
for (int i = 1; i < emailPrefix.length(); i++) {
// If email prefix respects all conditions, change result to true
char character = emailPrefix.charAt(i);
if (isValidPrefixChar(character)) {
// the previous char is '.', '_', '-' then you cannot have two valid prefix char together
if (nextHasToBeAlphaNumeric) {
result = false;
break;
} else {
// the next char has to be alphanumeric
result = true;
nextHasToBeAlphaNumeric = true;
}
} else if (isAlphanumeric(character)) {
result = true;
nextHasToBeAlphaNumeric = false;
} else {
result = false;
break;
}
}
}
return result;
}
我正在做一项不使用 Regex 验证电子邮件的学校作业。本练习的前提是学习方法并练习我们的批判性思维。我知道代码可以减少到更少的行数。
现在,我需要检查电子邮件前缀的所有条件('@'之前的字符):
- 至少包含一个字符。
- 它仅包含字母数字字符、下划线(‘_’)、句点(‘.’)和破折号(‘-’)。
- 下划线、句点或破折号后必须始终跟一个或多个字母数字字符。
- 第一个字符必须是字母数字。
有效前缀的示例是:“abc-d”、“abc.def”、“abc”、“abc_def”。
无效前缀的示例是:“abc-”、“abc..d”、“.abc”、“abc#def”。
我很难弄清楚第三个条件。到目前为止,我有这些满足其他条件的方法。
public static boolean isAlphanumeric(char c) {
return Character.isLetterOrDigit(c);
}
public static boolean isValidPrefixChar(char preChar) {
char[] prefixChar = new char[] {'-', '.', '_'};
for (int i = 0; i < prefixChar.length; i++) {
if (prefixChar[i] == preChar) {
return true;
} else if (isAlphanumeric(preChar)) {
return true;
}
}
return false;
}
public static boolean isValidPrefix(String emailPrefix) {
boolean result = false;
// To check if first character is alphanumeric
if (isAlphanumeric(emailPrefix.charAt(0)) && emailPrefix.length() > 1) {
for (int i = 0; i < emailPrefix.length(); i++) {
// If email prefix respects all conditions, change result to true
if (isValidPrefixChar(emailPrefix.charAt(i))) {
result = true;
} else {
result = false;
break;
}
}
}
return result;
}
让我们看看您的列表:
- 至少包含一个字符。
- 它仅包含字母数字字符、下划线(‘_’)、句点(‘.’)和破折号(‘-’)。
- 下划线、句点或破折号后必须始终跟一个或多个字母数字字符。
- 第一个字符必须是字母数字。
正如你所说,1、2、4 很简单。这就是我会做的。如果不正确,我的第一行将检查长度和 return false。然后我会遍历字符。在循环内;
- 设置布尔值 lastWasSpecial = false。
- 检查它是否为合法字符(条件 2)
- 如果索引 == 0,请检查它是否为字母数字(条件 4)
- 如果是特色菜之一:
- 如果设置了 lastWasSpecial,return false
- 设置 lastWasSpecial = true;
- 否则再次设置 lastWasSpecial = false
应该是大约 10 行 easily-readable 代码。
local-part
仅供参考,COMMERCIAL AT 符号 (@
) 之前的地址部分称为 local-part。
避免char
当遇到 BMP 之外的字符时,使用 char
的代码将会中断。作为 16 位值,char
不能表示大多数字符。
代码点
在处理单个字符时,请改用代码点。代码点是永久分配给 Unicode 中定义的 140,000 多个字符中的每一个的编号。
int[] codePoints = localPart.codePoints().toArray() ;
定义一个数组、列表或一组您可接受的标点字符。
int codePoint = "-".codePointAt( 0 ) ; // Annoying zero-based index counting.
要验证遇到的每个标点符号后跟一个 letter/digit,首先要确保标点符号不是最后一个字符。如果不是,则在数组中查找以下代码点。测试该代码点是否 is a letter or digit.
if( Character.isLetterOrDigit( codePoints[ i + 1 ] ) ) { … }
算法可以优化,但我尝试只更改一些行并使用相同的代码风格。我在评论里加了说明
public static boolean isAlphanumeric(char c) {
return Character.isLetterOrDigit(c);
}
public static boolean isValidPrefixChar(char preChar) {
char[] prefixChar = new char[]{'-', '.', '_'};
for (int i = 0; i < prefixChar.length; i++) {
if (prefixChar[i] == preChar) {
return true;
}
}
return false;
}
public static boolean isValidPrefix(String emailPrefix) {
boolean result = false;
// To check if first character is alphanumeric
if (isAlphanumeric(emailPrefix.charAt(0)) && emailPrefix.length() > 1) {
// this boolean is set to true when the next char has to be alphanumeric
boolean nextHasToBeAlphaNumeric = false;
// the for loop start from 1 because char 0 has been already checked
for (int i = 1; i < emailPrefix.length(); i++) {
// If email prefix respects all conditions, change result to true
char character = emailPrefix.charAt(i);
if (isValidPrefixChar(character)) {
// the previous char is '.', '_', '-' then you cannot have two valid prefix char together
if (nextHasToBeAlphaNumeric) {
result = false;
break;
} else {
// the next char has to be alphanumeric
result = true;
nextHasToBeAlphaNumeric = true;
}
} else if (isAlphanumeric(character)) {
result = true;
nextHasToBeAlphaNumeric = false;
} else {
result = false;
break;
}
}
}
return result;
}