【问题标题】:How to match sequences of consecutive Date like characters string in Dart?如何在 Dart 中匹配连续的日期序列,如字符串?
【发布时间】:2021-06-02 07:30:37
【问题描述】:

我有连续的字符作为日期,如 2021021514032020 我正在尝试转换为日期字符串,例如 2021.02.1514.03.2020

我的第一个问题是 2 格式类型的连续字符。喜欢:

1) 20210215
2) 14032020

我的第二个问题是将它们转换为日期字符串而不更改格式。喜欢:

1) 2021.02.15
2) 14.03.2020

当我搜索正则表达式时,找不到将上述 {20210215} 连续字符示例转换为日期 {2021.02.15} 字符串的任何模式。

什么是正确的正则表达式模式来转换我上面在 Dart 中描述的两种格式?

UPDATE-1:

我需要将此字符串“20210215”转换为“2021.02.15”作为字符串而不是日期时间。我还需要把这个字符串“14032020”变成这个字符串“14.03.2020”。而且我不想转向 DateTime 字符串。

首先我需要检测年份是在字符串的开头还是结尾。比在日、月和年字符串之间放置点 (.)。

UPDATE-2: 这是我能找到的最好的,但它会将 02 天或月变为 2。但我需要原样。

  var timestampString = '13022020';//'20200213';

  var re1 = RegExp(
    r'^'
    r'(?<year>\d{4})'
    r'(?<month>\d{2})'
    r'(?<day>\d{2})'
    r'$',
  );

  var re2 = RegExp(
    r'^'
    r'(?<day>\d{2})'
    r'(?<month>\d{2})'
    r'(?<year>\d{4})'
    r'$',
  );

  var dateTime;
  var match1 = re1.firstMatch(timestampString);
  if (match1 == null) {
    var match2 = re2.firstMatch(timestampString);
    if (match2 == null) {
      //throw FormatException('Unrecognized timestamp format');
      dateTime = '00.00.0000';
      print('DATE_TIME: $dateTime');
    } else {
      var _day = int.parse(match2.namedGroup('day'));
      var _month = int.parse(match2.namedGroup('month'));
      var _year = int.parse(match2.namedGroup('year'));
      dateTime = '$_day.$_month.$_year';
      print('DATE_TIME(match2): $dateTime');
    }
  } else {
    var _year = int.parse(match1.namedGroup('year'));
    var _month = int.parse(match1.namedGroup('month'));
    var _day = int.parse(match1.namedGroup('day'));
    dateTime = '$_year.$_month.$_day';
    print('DATE_TIME(match1): $dateTime');
  }

输出:

DATE_TIME: 2020.2.13

但我需要输出为 2020.02.13。

其次是 match1 也打印 1302.20.20 但是如果我删除 var match2 部分并且如果格式类似于 20200213 它可以工作,但不会像我在上面发布的那样打印 0。

【问题讨论】:

  • 你的年龄有限制吗?我的意思是,其中一个字符串可以有 1200 或 1912 还是它们都是 2020 和 2021?
  • 请查看顶部的链接。如果您仍有问题,请使用您尝试过的确切代码编辑问题并说明当前问题,然后通过评论告知。
  • 如果它是像“DDMMYYYY”这样的固定格式,那么使用组的正则表达式模式很简单。如果它不是固定格式,那么它会复杂得多,因为没有固有的方法来判断任意 8 个数字的字符串可以是什么格式。
  • @OmarSi 年份并不完全一样,但开始就像 1900 年,结束是...... 2021、2021 等。
  • @Abion47 传入文本格式为:DDMMYYYY 和 YYYYMMDD 类型。

标签: regex dart


【解决方案1】:

你可以使用

text.replaceAllMapped(RegExp(r'\b(?:((?:19|20)\d{2})(0?[1-9]|1[0-2])(0?[1-9]|[12][0-9]|3[01])|(0?[1-9]|[12][0-9]|3[01])(0?[1-9]|1[0-2])((?:19|20)\d{2}))\b'), (Match m) => m[4] == null ? "${m[1]}.${m[2]}.${m[3]}" : "${m[4]}.${m[5]}.${m[6]}")

\b(?:((?:19|20)\d{2})(0?[1-9]|1[0-2])(0?[1-9]|[12][0-9]|3[01])|(0?[1-9]|[12][0-9]|3[01])(0?[1-9]|1[0-2])((?:19|20)\d{2}))\b 正则表达式匹配

  • \b - 单词边界
  • (?: - 非捕获组的开始:
    • ((?:19|20)\d{2}) - 20 世纪和 21 世纪的年份
    • (0?[1-9]|1[0-2]) - 月
    • (0?[1-9]|[12][0-9]|3[01]) - 天
  • | - 或
    • (0?[1-9]|[12][0-9]|3[01]) - 天
    • (0?[1-9]|1[0-2]) - 月
    • ((?:19|20)\d{2}) - 年
  • ) - 小组结束
  • \b - 字边界。

请参阅regex demo

查看 Dart 演示:


void main() {
  final text = '13022020 and 20200213 20111919';
  print(text.replaceAllMapped(RegExp(r'\b(?:((?:19|20)\d{2})(0?[1-9]|1[0-2])(0?[1-9]|[12][0-9]|3[01])|(0?[1-9]|[12][0-9]|3[01])(0?[1-9]|1[0-2])((?:19|20)\d{2}))\b'), (Match m) => 
   m[4] == null ? "${m[1]}.${m[2]}.${m[3]}" : "${m[4]}.${m[5]}.${m[6]}"));
} 

返回13.02.2020 and 2020.02.13 20.11.1919

如果第 4 组为空,则第一个选择匹配,所以我们需要使用第 1、2 和 3 组。否则,我们用点连接第 4、5 和 6 组。

【讨论】:

    猜你喜欢
    • 2021-06-03
    • 1970-01-01
    • 2015-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多