简体   繁体   English

PHP中非常简单的正则表达式问题

[英]Fairly simple regex question in PHP

Ok, i'm a regex doofus. 好吧,我是regex doofus。 I only ever learn enough to get me by, but i would like to know how to do the below regex without using a php ternary operator in the middle of it. 我只学过足够的知识,但是我想知道如何在不使用php三元运算符的情况下执行以下正则表达式。 Also it may be ugly but it works... 另外它可能很难看,但是可以用...

'^". $date[0].(($date[0] == 0)?'?':'').$date[1]."[/.-]".$date[2].(($date[2] == 0)?'?':'').$date[3]."'";

uhm. as you can see im using a ternary operator to test if the date contains a 0. if it does.. then it can be ignored, if not then its a 1 or 2 and do not ignore. 如您所见,im使用三元运算符测试日期是否包含0。如果包含,则可以忽略,如果不包含则为1或2,请不要忽略。 i'm sure there is a way to write this with just regex? 我确定只有正则表达式可以写这种方法吗? If you know how then please tell me and i will be forever greatful. 如果您知道怎么办,请告诉我,我将永远幸福。 Also, just incase you wondering this is a regex in a mysql query. 另外,以防万一您想知道这是mysql查询中的正则表达式。

Are you looking for this? 您在找这个吗? match[1] is the month, match[2] is the day and match[3] is the year match [1]是月份,match [2]是日期,match [3]是年份

$regex = '#(0?[1-9]|1[0-2])[-/]([0-2]?[1-9]|3[01])[-/](19|20)?\d\d)#';

You have a couple problems here. 你这里有几个问题。

First, never ever put a text into a database that you haven't made sure is formatted correctly. 首先,永远不要将尚未确定格式正确的文本放入数据库。 The fact that the dates are in the database with and without the 0's is a problem. 日期存在于数据库中(带有和不带有0)的事实是一个问题。 Why aren't the dates in datetime fields where the database would make sure they are formatted correctly? 为什么数据库中的日期时间字段中的日期不能确保格式正确?

Second, the regex above only works in the US where 'mm/dd/yyyy' dates are used. 其次,上述正则表达式仅在使用“ mm / dd / yyyy”日期的美国有效。 Support for other date formats is impossible if you are tied to that regex. 如果您绑定到该正则表达式,则不可能支持其他日期格式。

Third, why are you doing this in the database? 第三,为什么要在数据库中执行此操作? Your example is WHERE birthday regex something.... That means you have this date before you are passing it to mySQL. 您的示例是WHERE生日正则表达式……。这意味着您有此日期,然后再将其传递给mySQL。 So fix the date in PHP first: 因此,首先在PHP中修复日期:

$date = strtotime($_GET['date']);
$sql = "select blah From blah WHERE birthday = '$date' blah";

There really isn't any easy way to simplify this. 确实没有任何简单的方法可以简化此过程。 The problem is that you are building a regular expression which forces you to test on zero no matter what. 问题在于您正在构建一个正则表达式,无论如何都将强制您对零进行测试。 You might be better off converting $date into a true date with mktime and then use that in your query. 您最好用mktime将$ date转换为真实日期,然后在查询中使用它。

$date1 = mktime(0,0,0, substr($date, 0, 2), substr($date, 2, 2));
$sqlquery = "select * from table WHERE table_date == $date1";

for($i = 0; $i < 3; $i++) {
    $date[i] = preg_replace($date[i], '0', '');
}

That vanishes any zero. 那消失为零。

Check the PHP documentation, it has tons of nice functions. 查看PHP文档,它有很多不错的功能。 www.php.net www.php.net

I'd recommend not having so much conditional logic built into a single statement that generates the regex. 我建议不要在生成正则表达式的单个语句中内置太多条件逻辑。 Even if there was a way to implement this as a native regex expression, I doubt it would be any more readable. 即使有一种方法可以将其实现为本地正则表达式,我也怀疑它是否更具可读性。 If the goal is make this snippet more readable, I'd suggest conditionally choosing between different regex expressions or conditionally building the various parts in separate steps, then stitch them together. 如果目标是使此片段更具可读性,我建议有条件地在不同的regex表达式之间进行选择,或有条件地在不同的步骤中构建各个部分,然后将它们缝合在一起。

JDany has a better solution, but the regex you are looking for is: JDany有一个更好的解决方案,但是您正在寻找的正则表达式是:

    Month         /            Day               /     Year
(0?[1-9]|1[0-2])[/-](0?[1-9]|[1-2][0-9]|3[0-1])[/-](19|20)?\d\d)

Note this regex doesn't handle/validate situations such as: 请注意,此正则表达式无法处理/验证以下情况:

  1. Months and their corresponding days (ie 28, 30, 31 days) 月及其对应的天数(即28、30、31天)

  2. Leap years 闰年

Good responses so far with regular expression solutions. 到目前为止,使用正则表达式解决方案的反应良好。

Here's another approach -- use the native PHP function strtotime () to normalize the string. 这是另一种方法-使用本地PHP函数strtotime ()对字符串进行规范化。 It's not perfect, but then neither is a regex solution when dealing with the many formats people might use as dates. 这并不完美,但是当处理人们可能用作日期的多种格式时,正则表达式解决方案也不是。

Here's how I would start to attack this: 这是我将如何开始对此进行攻击的方法:

<?php

// improve strtotime by eliminating dash ambiguity
function strtotimePlus($string) {
    $bads = array('-');
    $goods = array('/');
    return strtotime(str_replace($bads,$goods,$string));
}

// return date in fomat YYYY-MM-DD
function myDateFormat($timeformat) {
    return date("Y-m-d",$timeformat);
}

// convert free-form date string to YYYY-MM-DD
function betterDate($string) {
    return myDateFormat(strtotimePlus($string));

}

// samples from examples mentioned on the thread.
$dates = array();
$dates[] = "6/6/87";
$dates[] = "06/06/87";
$dates[] = "5.3.2001";
$dates[] = "5-2-82";
$dates[] = "1/1/83";

foreach($dates as $date) {
    print $date . " becomes " . betterDate($date) . "<br />";
}

Output: 输出:

6/6/87 becomes 1987-06-06
06/06/87 becomes 1987-06-06
5.3.2001 becomes 2001-03-05
5-2-82 becomes 1982-05-02
1/1/83 becomes 1983-01-01

Thankyou all for your answers! 谢谢大家的答案!

A few things to note: 注意事项:
1) i didnt design this database, nor want to make any drastic changes to it. 1)我没有设计这个数据库,也不想对它做任何大的改变。
2) i know very well how to convert strings to dates and vice-versa and all that jazz. 2)我非常了解如何将字符串转换为日期,反之亦然以及所有爵士乐。
3) what i want to know is if there is a regex operator/expression that can do away with my ternary statement in the middle of it. 3)我想知道的是是否有一个正则表达式运算符/表达式可以消除中间的三元语句。

I realise i wasnt very clear. 我意识到我不是很清楚。 I have birthdays of all formats in the database, its a large database. 数据库中有各种格式的生日文件,数据库很大。 I am pulling dates out of the database two weeks before the birthday of the client. 我要在客户生日前两周从数据库中取出日期。
So..! 所以..! i take the current date add 14 to it and i would have "17/06/09" this is the date i need to check against the 2000+ dates in the database. 我将当前日期加上14,就得到“ 17/06/09”,这是我需要对照数据库中2000多个日期进行检查的日期。 this date IS formatted nicely. 这个日期的格式很好。 i like nice things. 我喜欢美好的事物。 specially dates. 特别是日期。 nice dates. 美好的约会。 anyways.... 无论如何....

i need to check my date against the mish mash in the database and the only ways i know of checking this against the database is by 我需要根据数据库中的Mash mash检查日期,而我知道根据数据库进行检查的唯一方法是
A) pulling every record out, formatting the crappy date correctly and then checking it against mine (which is what i was doing... very cpu intensive) A)拉出每条记录,正确格式化糟糕的日期,然后对照我的进行检查(这是我正在做的...占用大量CPU)
B) having a regex clause in my sql and retrieving only dates that match my specifications. B)在我的sql中有一个regex子句,并且仅检索符合我的规范的日期。

Is my logic sound? 我的逻辑健全吗? I Hope so. 希望如此。 If not then please point out the obvious to me and i will send you some candy*. 如果没有,请给我指出明显的地方,我会给你一些糖果*。




*Imaginary candy *假想糖果

Don't mean to get downvoted for jumping on fix-the-underlying-problem, but... 并不是要因解决基本问题而心灰意冷,而是...

If you have all these varying date formats right now, that seems to me to mean that the other apps are fine with the varying formats, and can parse, understand, or at least present the date in whatever form it's in as a string. 如果您现在具有所有这些不同的日期格式,在我看来,这意味着其他应用程序可以使用不同的格式,并且可以解析,理解或至少以字符串形式显示日期。 So, as a string, the other apps that use this data can accept it in any of the forms it's now in. 因此,作为字符串,使用此数据的其他应用程序可以以现在使用的任何形式接受它。

So it seems to me, that if all the date data continued to be strings, but just happened to all be in one particular layout (say, the international YYYY-MM-DD), that all the other apps would be just as happy with this format as any other, and any script (such as yours) which had to parse the actual value could do so more simply. 因此在我看来,如果所有日期数据都继续为字符串,但恰好全部都位于一种特定的布局中(例如国际YYYY-MM-DD),那么其他所有应用程序都将同样满意这种格式和其他格式一样,必须解析实际值的任何脚本(例如您的脚本)都可以更简单地实现。

So, my question is, are you allowed to scrub and reformat the strings, keeping them strings, so they all look the same? 因此,我的问题是,是否允许您擦洗并重新格式化字符串,使其保持字符串状态,以使它们看起来都一样? I mean run a cleanup job before your job (either as a separate maintenance task, or just before you work with the data) which checks if a date is in your format, and reformats it and stores it back in the database as a string in the best format if it's not. 我的意思是在工作之前运行清理作业(作为单独的维护任务,或者就在使用数据之前),该清理作业检查日期是否为您的格式,然后将其重新格式化并以字符串形式存储在数据库中如果不是,则为最佳格式。

A separate question about your goal of finding two weeks earlier than the date in the database. 关于您要在数据库中的日期之前两周找到目标的问题。 How do you know that the user input a day or a month first, if both values are less than 12? 如果两个值都小于12,您怎么知道用户首先输入一天还是一个月? For a date like 1/5/06, how do you know whether the user meant 1 May or 5 January? 对于1/5/06这样的日期,您如何知道用户是5月1日还是1月5日? I think you have to solve this, or at least make a decision about it, before you can subtract 14 days. 我认为您必须解决这个问题,或者至少要对此做出决定,然后再减去14天。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM