php对用户输入的非标准格式日期匹配
程序员文章站
2022-04-19 23:40:28
...
这两天在做的项目中需要对用户输入的日期进行匹配,匹配的格式范围 包括: 2001.4.3 六月五号 七月十五 一一年四月三日 二零一三年五月六日 01年3月7日 2011年3月31日 今天、明天、下周一、周六 使用的是正则来处理,值得注意的是再utf8编码下,正则使用\u选
这两天在做的项目中需要对用户输入的日期进行匹配,匹配的格式范围 包括:
2001.4.3
六月五号
七月十五
一一年四月三日
二零一三年五月六日
01年3月7日
2011年3月31日
今天、明天、下周一、周六
使用的是正则来处理,值得注意的是再utf8编码下,正则使用\u选项就能在表达式中直接输入中文。一下贴出代码:
1 //时间标识%6.5% 2 private function analyze_time( $content ){ 3 $time = false; 4 5 if( preg_match( '/%.*?%/', $content, $matches ) ){ 6 $time_str = trim( substr( $matches[0], 1, strlen( $matches[0] ) - 2 ) ); 7 $time = $this -> analyze_time_day( $time_str ); 8 (!$time ) && $time = $this -> analyze_time_week( $time_str ); 9 (!$time ) && $time = $this -> analyze_time_date( $time_str ); 10 } 11 return $time; 12 } 13 14 function analyze_time_day( $content ){ 15 $day = array( 16 '今天' => 0, 17 '明天' => 3600 * 24, 18 '后天' => 3600 * 48, 19 '大后天' => 3600 * 72, 20 ); 21 return isset( $day[$content] )?$day[$content]:false; 22 } 23 24 function analyze_time_week( $content ){ 25 26 27 $now = now(); 28 $time = 0; 29 $week = array( "周", "礼拜", "星期" ); 30 $week_pre = array( "下", "下个" ); 31 $week_day = array( "一" => 1, "二" => 2, "三" => 3, "四" => 4, "五" => 5, "六" => 6, "天" => 7, "日" => 7 ); 32 33 //模式一,匹配 "周一" , "下周一", "周日"; 34 $reg1 = "/^(" . implode( "|", $week_pre ) . ")?(" . implode( "|", $week ) . ")(" . implode( "|", array_keys( $week_day ) ) . ")/u"; 35 preg_match_all( $reg1, $content, $match ); 36 if( (!empty( $match[0] )) && (!empty( $match[2] )) && (!empty( $match[3] )) ){ 37 //匹配结果数组 1:下; 2:星期 3:一 38 //判断今天 39 $w = date( "w", $now ); 40 $w == 0 && $w = 7; 41 //判断输入时期 42 $w_2 = $week_day[$match[3][0]]; 43 if( empty( $match[1][0] ) ){ 44 $time = $w_2 - $w > 0 ? 3600 * 24 * ($w_2 - $w) : 0; 45 }else{ 46 $time = 3600 * 24 * ($w_2 - $w + 7 ); 47 } 48 } 49 return $time == 0 ? false : ( int ) $now + ( int ) $time; 50 } 51 52 function analyze_time_date( $content ){ 53 $now = now(); 54 $content = str_replace( ".", "-", $content ); 55 if( strtotime( $content ) ){ 56 return strtotime( $content ); 57 } 58 59 $number = array( "零", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二" ); 60 $number_2 = $number; 61 $number_2 = array_splice( $number_2, 1, 10 ); 62 $reg2_2 = "/(0?[1-9]|10|11|12|[" . implode( "", $number_2 ) . "]|(十一|十二))月([012]?[0-9]|30|31|(十|二十|三十)?[" . implode( "", $number_2 ) . "十]?)日?/u"; 63 preg_match_all( $reg2_2, $content, $match ); 64 // print_r( $match ); 65 //匹配数组 1:月份 3:日 66 67 if( (!empty( $match[0] )) && (!empty( $match[1][0] )) && (!empty( $match[3][0] )) ){ 68 $str_month = $match[1][0]; 69 $str_day = $match[3][0]; 70 $month = is_numeric( $str_month ) ? $str_month : false; 71 if( !$month ){ 72 foreach( $number as $k => $v ){ 73 if( $v == $str_month ){ 74 $month = $k; 75 } 76 } 77 } 78 // echo "month:{$month}"; 79 80 $day = is_numeric( $str_day ) ? $str_day : false; 81 if( !$day ){ 82 $day = array_search( $str_day, $number ); 83 if( !$day ){ 84 $number_3 = $number; 85 $number_3 = array_splice( $number_3, 1, 9 ); 86 $re_day = preg_match_all( "/([一二三])?(十)([" . implode( "", $number_3 ) . "])?/u", $str_day, $match_2 ); 87 $day = array_search( $match_2[1][0], $number ) ? array_search( $match_2[1][0], $number ) * 10 : 10; 88 $day += array_search( $match_2[3][0], $number ) ? array_search( $match_2[3][0], $number ) : 0; 89 } 90 } 91 // echo "day:{$day}"; 92 93 if( $month == false || $day == false ){ 94 return false; 95 } 96 97 if( $match[0][0] == $content ){ 98 //无年份前缀 99 $output = date( "Y", $now ) . "-" . $month . "-" . $day; 100 }else{ 101 //有年份前缀 102 $year = $this -> analyze_time_year( str_replace( $match[0][0], "", $content ) ); 103 if( $year ){ 104 $output = $year . "-" . $month . "-" . $day; 105 }else{ 106 return false; 107 } 108 } 109 return strtotime( $output ); 110 } 111 return false; 112 } 113 114 115 function analyze_time_year( $content ){ 116 $number = array( "零", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十" ); 117 118 119 //模式二 --一,匹配年 2001年,01年,零一年,二九年,二零一九年 120 //1-9 121 $number_1 = $number; 122 $number_1 = array_splice( $number_1, 0, 10 ); 123 $reg2_1 = "/((20|二零)?([12一二])([0-9]|[" . implode( "", $number_1 ) . "]))(?(1)年)/u"; 124 preg_match_all( $reg2_1, $content, $match ); 125 if( (!empty( $match[0] )) && (!empty( $match[3][0] )) && (!empty( $match[4][0] )) ){ 126 $day = ( is_numeric( $match[3][0] ) ? $match[3][0] : array_search( $match[3][0], $number ) ) * 10; 127 $day += is_numeric( $match[4][0] ) ? $match[4][0] : array_search( $match[4][0], $number ); 128 }else{ 129 return false; 130 } 131 132 return $day ? $day + 2000 : false; 133 }
每个函数都可以单独使用。