如何编写正则表达式来识别 android 中字符串的不同日期模式?
How to write regex to identify different date patterns of a String in android?
我在 API 秒内收到不同的日期模式。有什么方法可以识别 API 中接收到的字符串的日期模式,以便我可以在不引发任何日期异常的情况下格式化它们?
使用此字符串扩展函数来识别字符串的日期模式。
/**
* Created By Sweta
* * Method to check Input Date Pattern Before before Formatting
* @param outputPattern This parameter takes the output DATE Pattern as String
* Checks four patterns: "dd/mm/yyyy", "mm/dd/yyyy hh:MM:ss", "dd MMM yyyy", "yyyy-MM-dd",
* "yyyy-MM-dd'T'HH:mm:ss", "dd-MMM-yyyy", "MM/dd/yyyy hh:mm:ss a", "dd-mm-yyyy hh:mm:ss",
* "dd-mm-yyyy hh:mm:ss a", "mm/dd/yyyy hh:mm:ss", "mm/dd/yyyy"
*/
@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
fun String.checkInputDatePatternBefore(outputPattern: String): String {
//"dd/mm/yyyy"
val regex1 = "^(3[01]|[12][0-9]|0[1-9]|[1-9])/(1[0-2]|0[1-9]|[1-9])/[0-9]{4}$".toRegex()
//"mm/dd/yyyy hh:MM:ss"
val regex2 =
"^(1[0-2]|0[1-9]|[1-9])/(3[01]|[12][0-9]|0[1-9]|[1-9])/[0-9]{4} [0-9][0-9]:([0]?[0-5]
[0-9]|[0-9]):([0-5][0-9])$"
.toRegex()
//"dd MMM yyyy"
val regex3 = "(3[01]|[12][0-9]|0[1-9]|[1-9])[\s][a-zA-Z]{3}[\s][0-9]{4}$".toRegex()
//"yyyy-MM-dd"
val regex4 =
"([0-9]{4})[\-](1[0-2]|0[1-9]|[1-9])[\-](3[01]|[12][0-9]|0[1-9]|[1-9])$".toRegex()
//"yyyy-MM-dd'T'HH:mm:ss"
val regex5 =
"([0-9]{4})[\-](1[0-2]|0[1-9]|[1-9])[\-](3[01]|[12][0-9]|0[1-9])[T][0-9][0-9]:([0]?
[0-5][0-9]|[0-9]):([0-5][0-9])$".toRegex()
//"dd-MMM-yyyy"
val regex6 = "(3[01]|[12][0-9]|0[1-9]|[1-9])[\-][a-zA-Z]{3}[\-][0-9]{4}$".toRegex()
//"MM/dd/yyyy hh:mm:ss a"
val regex7 =
"^((1[0-2]|0[1-9]|[1-9])/3[01]|[12][0-9]|0[1-9]|[1-9])/[0-9]{4}[\s][0-9][0-9]:([0]?
[0-5][0-9]|[0-9]):([0-5][0-9])[\s][a-zA-Z]{2}$"
.toRegex()
//28-02-2022 12:12:24
//"dd-mm-yyyy hh:mm:ss"
val regex8 =
"(3[01]|[12][0-9]|0[1-9]|[1-9])[\-](1[0-2]|0[1-9]|[1-9])[\-][0-9]{4}[\s][0-9][0-9]:
([0]?[0-5][0-9]|[0-9]):([0-5][0-9])$".toRegex()
//"dd-mm-yyyy hh:mm:ss a"
val regex9 =
"(3[01]|[12][0-9]|0[1-9]|[1-9])[\-](1[0-2]|0[1-9]|[1-9])[\-][0-9]{4}[\s][0-9][0-9]:
([0]?[0-5][0-9]|[0-9]):([0-5][0-9])[\s][a-zA-Z]{2}$".toRegex()
//"mm/dd/yyyy hh:mm:ss"
val regex10 =
"(1[0-2]|0[1-9]|[1-9])[/](3[01]|[12][0-9]|0[1-9]|[1-9])[/][0-9]{4}[\s][0-9][0-9]:
([0]?[0-5][0-9]|[0-9]):([0-5][0-9])$"
.toRegex()
//"mm/dd/yyyy"
val regex11 =
"(1[0-2]|0[1-9]|[1-9])[/](3[01]|[12][0-9]|0[1-9]|[1-9])[/][0-9]{4}$"
.toRegex()
val bool1: Boolean = regex1.matches(this)
val bool2: Boolean = regex2.matches(this)
val bool3: Boolean = regex3.matches(this)
val bool4: Boolean = regex4.matches(this)
val bool5: Boolean = regex5.matches(this)
val bool6: Boolean = regex6.matches(this)
val bool7: Boolean = regex7.matches(this)
val bool8: Boolean = regex8.matches(this)
val bool9: Boolean = regex9.matches(this)
val bool10: Boolean = regex10.matches(this)
val bool11: Boolean = regex11.matches(this)
when {
bool1 -> {
Log.d(TAG, "Pattern dd/mm/yyyy")
return "Pattern dd/mm/yyyy"
}
bool2 -> {
Log.d(TAG, "Pattern mm/dd/yyyy hh:MM:ss")
return "Pattern mm/dd/yyyy hh:MM:ss"
}
bool3 -> {
Log.d(TAG, "Pattern dd MMM yyyy")
return "Pattern dd MMM yyyy"
}
bool4 -> {
Log.d(TAG, "Pattern yyyy-MM-dd")
return "Pattern yyyy-MM-dd"
}
bool5 -> {
Log.d(TAG, "Pattern yyyy-MM-dd'T'HH:mm:ss")
return "Pattern yyyy-MM-dd'T'HH:mm:ss"
}
bool6 -> {
Log.d(TAG, "Pattern dd-MMM-yyyy")
return "Pattern dd-MMM-yyyy"
}
bool7 -> {
Log.d(TAG, "Pattern MM/dd/yyyy hh:mm:ss a")
return "Pattern MM/dd/yyyy hh:mm:ss a"
}
bool8 -> {
Log.d(TAG, "Pattern dd-mm-yyyy hh:mm:ss")
return "Pattern dd-mm-yyyy hh:mm:ss"
}
bool9 -> {
Log.d(TAG, "Pattern dd-mm-yyyy hh:mm:ss AM/PM")
return "Pattern dd-mm-yyyy hh:mm:ss AM/PM"
}
bool10 -> {
Log.d(TAG, "Pattern mm/dd/yyyy hh:mm:ss")
return "Pattern mm/dd/yyyy hh:mm:ss"
}
bool11 -> {
Log.d(TAG, "Pattern mm/dd/yyyy")
return "Pattern mm/dd/yyyy"
}
else -> {
Log.d(TAG, "Date pattern not recognized!")
Log.d(TAG, this)
return "Date pattern not recognized!"
}
}
}
提供 的替代实现。代码审查时间! (不包括此方法或正则表达式的正确性。)
大部分代码的重复性本应暗示它需要重构。除了正则表达式定义之外的所有内容都只是重复的块,例如:
val bool1: Boolean = regex1.matches(this)
val bool2: Boolean = regex2.matches(this)
...
val bool11: Boolean = regex11.matches(this)
还有
when {
bool1 -> {
Log.d(TAG, "Pattern dd/mm/yyyy")
return "Pattern dd/mm/yyyy"
}
bool2 -> {
Log.d(TAG, "Pattern mm/dd/yyyy hh:MM:ss")
return "Pattern mm/dd/yyyy hh:MM:ss"
}
...
}
表单相同,但变量和消息不同。并且按照当前的逻辑,在第一次匹配时停止。如果添加了新的正则表达式,则需要在 when
.
中添加更多 val bool12/13/14/15
和更多检查
相反,将所有内容放入一个集合中,如 List
。并将日期格式与正则表达式相关联,在 Map
. 完成这两项更改后,唯一剩下的就是必须定义的正则表达式。您还可以使用相关方法将每个模式名称和正则表达式放入 data class
。
/* label is the date format and pattern is the regex for that format.
* result() provides a message (string) when trying to match, but can be
* modified to get a bool result, like in boolResult(). */
data class DatePatternChecker(val label: String, val pattern: Regex) {
fun result(dateString: String): String? = if (pattern.matches(dateString)) "Pattern is $label" else null
fun boolResult(dateString: String): Boolean = pattern.matches(dateString)
constructor(labelPattern: Map.Entry<String, Regex>) : this(labelPattern.key, labelPattern.value)
}
val datePatternChecks = mapOf(
"dd/mm/yyyy" to
"^(3[01]|[12][0-9]|0[1-9]|[1-9])/(1[0-2]|0[1-9]|[1-9])/[0-9]{4}$".toRegex(),
"mm/dd/yyyy hh:MM:ss" to
"^(1[0-2]|0[1-9]|[1-9])/(3[01]|[12][0-9]|0[1-9]|[1-9])/[0-9]{4} [0-9][0-9]:([0]?[0-5][0-9]|[0-9]):([0-5][0-9])$".toRegex(),
// etc.
).map(::DatePatternChecker)
fun String.datePattern(): String = datePatternChecks
.firstNotNullOfOrNull { it.result(this) }
?: "Date pattern not recognized!"
// better
fun String.datePatternByBool(): String = datePatternChecks
.firstOrNull { it.boolResult(this) }
?.run { "Pattern is $label" }
?: "Date pattern not recognized!"
// using datePattern
println("21/01/2001".datePattern()) // Pattern is dd/mm/yyyy
println("12/31/2001 13:55:59".datePattern()) // Pattern is mm/dd/yyyy hh:MM:ss
println("99/32/2001".datePattern()) // Date pattern not recognized!
// using datePatternByBool
println("21/01/2001".datePatternByBool()) // Pattern is dd/mm/yyyy
println("12/31/2001 13:55:59".datePatternByBool()) // Pattern is mm/dd/yyyy hh:MM:ss
println("99/32/2001".datePatternByBool()) // Date pattern not recognized!
这更实用并且没有重复。如果需要添加新模式或规则,只需将其放入datePatternChecks
中正确的position/order;无需其他更改即可使用新模式。
我在 API 秒内收到不同的日期模式。有什么方法可以识别 API 中接收到的字符串的日期模式,以便我可以在不引发任何日期异常的情况下格式化它们?
使用此字符串扩展函数来识别字符串的日期模式。
/**
* Created By Sweta
* * Method to check Input Date Pattern Before before Formatting
* @param outputPattern This parameter takes the output DATE Pattern as String
* Checks four patterns: "dd/mm/yyyy", "mm/dd/yyyy hh:MM:ss", "dd MMM yyyy", "yyyy-MM-dd",
* "yyyy-MM-dd'T'HH:mm:ss", "dd-MMM-yyyy", "MM/dd/yyyy hh:mm:ss a", "dd-mm-yyyy hh:mm:ss",
* "dd-mm-yyyy hh:mm:ss a", "mm/dd/yyyy hh:mm:ss", "mm/dd/yyyy"
*/
@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
fun String.checkInputDatePatternBefore(outputPattern: String): String {
//"dd/mm/yyyy"
val regex1 = "^(3[01]|[12][0-9]|0[1-9]|[1-9])/(1[0-2]|0[1-9]|[1-9])/[0-9]{4}$".toRegex()
//"mm/dd/yyyy hh:MM:ss"
val regex2 =
"^(1[0-2]|0[1-9]|[1-9])/(3[01]|[12][0-9]|0[1-9]|[1-9])/[0-9]{4} [0-9][0-9]:([0]?[0-5]
[0-9]|[0-9]):([0-5][0-9])$"
.toRegex()
//"dd MMM yyyy"
val regex3 = "(3[01]|[12][0-9]|0[1-9]|[1-9])[\s][a-zA-Z]{3}[\s][0-9]{4}$".toRegex()
//"yyyy-MM-dd"
val regex4 =
"([0-9]{4})[\-](1[0-2]|0[1-9]|[1-9])[\-](3[01]|[12][0-9]|0[1-9]|[1-9])$".toRegex()
//"yyyy-MM-dd'T'HH:mm:ss"
val regex5 =
"([0-9]{4})[\-](1[0-2]|0[1-9]|[1-9])[\-](3[01]|[12][0-9]|0[1-9])[T][0-9][0-9]:([0]?
[0-5][0-9]|[0-9]):([0-5][0-9])$".toRegex()
//"dd-MMM-yyyy"
val regex6 = "(3[01]|[12][0-9]|0[1-9]|[1-9])[\-][a-zA-Z]{3}[\-][0-9]{4}$".toRegex()
//"MM/dd/yyyy hh:mm:ss a"
val regex7 =
"^((1[0-2]|0[1-9]|[1-9])/3[01]|[12][0-9]|0[1-9]|[1-9])/[0-9]{4}[\s][0-9][0-9]:([0]?
[0-5][0-9]|[0-9]):([0-5][0-9])[\s][a-zA-Z]{2}$"
.toRegex()
//28-02-2022 12:12:24
//"dd-mm-yyyy hh:mm:ss"
val regex8 =
"(3[01]|[12][0-9]|0[1-9]|[1-9])[\-](1[0-2]|0[1-9]|[1-9])[\-][0-9]{4}[\s][0-9][0-9]:
([0]?[0-5][0-9]|[0-9]):([0-5][0-9])$".toRegex()
//"dd-mm-yyyy hh:mm:ss a"
val regex9 =
"(3[01]|[12][0-9]|0[1-9]|[1-9])[\-](1[0-2]|0[1-9]|[1-9])[\-][0-9]{4}[\s][0-9][0-9]:
([0]?[0-5][0-9]|[0-9]):([0-5][0-9])[\s][a-zA-Z]{2}$".toRegex()
//"mm/dd/yyyy hh:mm:ss"
val regex10 =
"(1[0-2]|0[1-9]|[1-9])[/](3[01]|[12][0-9]|0[1-9]|[1-9])[/][0-9]{4}[\s][0-9][0-9]:
([0]?[0-5][0-9]|[0-9]):([0-5][0-9])$"
.toRegex()
//"mm/dd/yyyy"
val regex11 =
"(1[0-2]|0[1-9]|[1-9])[/](3[01]|[12][0-9]|0[1-9]|[1-9])[/][0-9]{4}$"
.toRegex()
val bool1: Boolean = regex1.matches(this)
val bool2: Boolean = regex2.matches(this)
val bool3: Boolean = regex3.matches(this)
val bool4: Boolean = regex4.matches(this)
val bool5: Boolean = regex5.matches(this)
val bool6: Boolean = regex6.matches(this)
val bool7: Boolean = regex7.matches(this)
val bool8: Boolean = regex8.matches(this)
val bool9: Boolean = regex9.matches(this)
val bool10: Boolean = regex10.matches(this)
val bool11: Boolean = regex11.matches(this)
when {
bool1 -> {
Log.d(TAG, "Pattern dd/mm/yyyy")
return "Pattern dd/mm/yyyy"
}
bool2 -> {
Log.d(TAG, "Pattern mm/dd/yyyy hh:MM:ss")
return "Pattern mm/dd/yyyy hh:MM:ss"
}
bool3 -> {
Log.d(TAG, "Pattern dd MMM yyyy")
return "Pattern dd MMM yyyy"
}
bool4 -> {
Log.d(TAG, "Pattern yyyy-MM-dd")
return "Pattern yyyy-MM-dd"
}
bool5 -> {
Log.d(TAG, "Pattern yyyy-MM-dd'T'HH:mm:ss")
return "Pattern yyyy-MM-dd'T'HH:mm:ss"
}
bool6 -> {
Log.d(TAG, "Pattern dd-MMM-yyyy")
return "Pattern dd-MMM-yyyy"
}
bool7 -> {
Log.d(TAG, "Pattern MM/dd/yyyy hh:mm:ss a")
return "Pattern MM/dd/yyyy hh:mm:ss a"
}
bool8 -> {
Log.d(TAG, "Pattern dd-mm-yyyy hh:mm:ss")
return "Pattern dd-mm-yyyy hh:mm:ss"
}
bool9 -> {
Log.d(TAG, "Pattern dd-mm-yyyy hh:mm:ss AM/PM")
return "Pattern dd-mm-yyyy hh:mm:ss AM/PM"
}
bool10 -> {
Log.d(TAG, "Pattern mm/dd/yyyy hh:mm:ss")
return "Pattern mm/dd/yyyy hh:mm:ss"
}
bool11 -> {
Log.d(TAG, "Pattern mm/dd/yyyy")
return "Pattern mm/dd/yyyy"
}
else -> {
Log.d(TAG, "Date pattern not recognized!")
Log.d(TAG, this)
return "Date pattern not recognized!"
}
}
}
提供
大部分代码的重复性本应暗示它需要重构。除了正则表达式定义之外的所有内容都只是重复的块,例如:
val bool1: Boolean = regex1.matches(this) val bool2: Boolean = regex2.matches(this) ... val bool11: Boolean = regex11.matches(this)
还有
when { bool1 -> { Log.d(TAG, "Pattern dd/mm/yyyy") return "Pattern dd/mm/yyyy" } bool2 -> { Log.d(TAG, "Pattern mm/dd/yyyy hh:MM:ss") return "Pattern mm/dd/yyyy hh:MM:ss" } ... }
表单相同,但变量和消息不同。并且按照当前的逻辑,在第一次匹配时停止。如果添加了新的正则表达式,则需要在 when
.
val bool12/13/14/15
和更多检查
相反,将所有内容放入一个集合中,如 List
。并将日期格式与正则表达式相关联,在 Map
. 完成这两项更改后,唯一剩下的就是必须定义的正则表达式。您还可以使用相关方法将每个模式名称和正则表达式放入 data class
。
/* label is the date format and pattern is the regex for that format.
* result() provides a message (string) when trying to match, but can be
* modified to get a bool result, like in boolResult(). */
data class DatePatternChecker(val label: String, val pattern: Regex) {
fun result(dateString: String): String? = if (pattern.matches(dateString)) "Pattern is $label" else null
fun boolResult(dateString: String): Boolean = pattern.matches(dateString)
constructor(labelPattern: Map.Entry<String, Regex>) : this(labelPattern.key, labelPattern.value)
}
val datePatternChecks = mapOf(
"dd/mm/yyyy" to
"^(3[01]|[12][0-9]|0[1-9]|[1-9])/(1[0-2]|0[1-9]|[1-9])/[0-9]{4}$".toRegex(),
"mm/dd/yyyy hh:MM:ss" to
"^(1[0-2]|0[1-9]|[1-9])/(3[01]|[12][0-9]|0[1-9]|[1-9])/[0-9]{4} [0-9][0-9]:([0]?[0-5][0-9]|[0-9]):([0-5][0-9])$".toRegex(),
// etc.
).map(::DatePatternChecker)
fun String.datePattern(): String = datePatternChecks
.firstNotNullOfOrNull { it.result(this) }
?: "Date pattern not recognized!"
// better
fun String.datePatternByBool(): String = datePatternChecks
.firstOrNull { it.boolResult(this) }
?.run { "Pattern is $label" }
?: "Date pattern not recognized!"
// using datePattern
println("21/01/2001".datePattern()) // Pattern is dd/mm/yyyy
println("12/31/2001 13:55:59".datePattern()) // Pattern is mm/dd/yyyy hh:MM:ss
println("99/32/2001".datePattern()) // Date pattern not recognized!
// using datePatternByBool
println("21/01/2001".datePatternByBool()) // Pattern is dd/mm/yyyy
println("12/31/2001 13:55:59".datePatternByBool()) // Pattern is mm/dd/yyyy hh:MM:ss
println("99/32/2001".datePatternByBool()) // Date pattern not recognized!
这更实用并且没有重复。如果需要添加新模式或规则,只需将其放入datePatternChecks
中正确的position/order;无需其他更改即可使用新模式。