PHP oldukça basit regex soru

9 Cevap php

Tamam, ben bir regex şapşal değilim. Ben sadece şimdiye kadar beni almak için yeterli bilgi, ama bunun ortasında bir php üçlü operatörü kullanmadan aşağıdaki regex nasıl bilmek istiyorum. Ayrıca çirkin olabilir ama işe yarıyor ...

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

uhm. o .. o zaman göz ardı edilebilir yapar eğer, tarih bir 0. içeriyorsa sınamak için bir üçlü operatörü kullanarak im görebileceğiniz gibi değilse o zaman onun bir 1 ya da 2 ve gözardı etmiyoruz. Ben sadece regex ile yazmak için bir yol olduğundan emin değilim? Lütfen bana o zaman nasıl biliyor ve eğer ben sonsuza kadar minnettar olacaktır. Ayrıca, sadece örtmek bu merak bir mysql sorguda bir regex olduğunu.

9 Cevap

Bu arıyorsun? maç [1] ay, maç [2] gün ve maç [3] yıl

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

Burada birkaç sorunlar var.

Öncelikle, hiç doğru emin biçimlendirilmiş yapmamış bir veritabanına bir metin koymak asla. Tarihleri ​​ile ve 0 olmadan veritabanında olduğu gerçeği bir sorundur. Neden veritabanı doğru emin onlar biçimlendirilmiş yapacak datetime alanlarında tarihleri ​​değil mi?

İkincisi, sadece yukarıda regex 'aa / gg / yyyy' tarihleri ​​kullanıldığı ABD'de çalışıyor. Bunu regex bağlı ise diğer tarih biçimleri için destek imkansızdır.

Üçüncü olarak, neden veritabanında yapıyorsun? Sizin örnek NEREDE doğum regex şey .... Yani mySQL geçirmeden önce bu tarihi var demektir. Bunun için ilk önce PHP tarihini düzeltmek:

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

Gerçekten bu basitleştirmek için herhangi bir kolay yolu yok. Sorun ne olursa olsun sıfıra üzerinde test zorlayan bir normal ifade inşa ediyoruz. Sen mktime ile gerçek bir tarih haline $ tarih dönüştürerek daha iyi olacak ve daha sonra sorguda bu kullanabilirsiniz.

$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', '');
}

Yani herhangi bir sıfır kaybolur.

PHP belgelerini kontrol edin, güzel fonksiyonlar ton vardır. www.php.net

Ben regex oluşturan tek bir deyim yerleşik çok koşullu mantığı sahip değil tavsiye ederim. Yerli bir regex ifadesi olarak bunu uygulamak için bir yol var olsa bile, ben bir daha okunabilir olacağını sanmıyorum. Amacınız bu pasajı daha okunabilir hale olursa, ben bunları birleştirmek, sonra şartlı farklı regex ifadeler arasında tercih veya koşullu ayrı adımda çeşitli yerlerinde inşa öneririm.

JDany daha iyi bir çözüm var, ama aradığınız regex olduğunu:

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

Bu regex gibi durumlarla doğrulamak / işlemek değil Not:

  1. Ay ve bunlara karşılık gelen gün (yani 28, 30, 31 gün)

  2. Leap yıl

Düzenli ifade çözümleri ile bugüne kadar iyi tepkiler.

Burada başka bir yaklaşım - dize normalleştirmek için yerli PHP işlevi strtotime () kullanın. O mükemmel değil, ama insanlar tarih olarak kullanabilir birçok biçimleri ile uğraşırken daha sonra ne bir regex çözümdür.

İşte bu saldırı başlamak istiyorum nasıl:

<?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 />";
}

Çıktı:

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

Cevaplar için teşekkür ederim tüm!

A few things to note:
1) i didnt design this database, nor want to make any drastic changes to it.
2) i know very well how to convert strings to dates and vice-versa and all that jazz.
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.

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. 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
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)
B) having a regex clause in my sql and retrieving only dates that match my specifications.

Benim mantık ses mi? Öyle umuyoruz. Eğer değilse o zaman benim için bariz işaret lütfen ve ben * bazı şeker göndereceğiz.


* Hayali şeker

Fix--yatan-problem üzerinde atlama için downvoted almak demek, ama ... yok

Şu anda bütün bu farklı tarih biçimleri varsa, bu diğer uygulamalar değişen biçimleri ile ince demek gibi geliyor bana, ve, ayrıştırmak, anlamak ya da en azından bir dize olarak ne varsa form tarihini sunabilirsiniz. Yani, bir dize olarak, bu verileri kullanabilirsiniz diğer uygulamalar içeri şimdi nerede formlardan herhangi bunu kabul edebilir

Yani tüm tarih veri dizeleri olmaya devam etti, ama eğer sadece tek bir özellikle düzen olması oldu ki, bana görünüyor (diyelim ki, uluslararası YYYY-AA-GG), tüm diğer uygulamalar ile mutlu olacağını başka olarak bu biçim, ve gerçek değerini ayrıştırmak zorunda (örneğin sizinki gibi) herhangi bir komut dosyası daha basit bunu yapabilirdi.

Yani, benim soru, sen dizeleri tutarak, dizeleri fırçalayın ve yeniden biçimlendirmek için izin verilir, böylece hepsi aynı görünüyor? Ben bir tarih senin formatında olup olmadığını kontrol eder, ve bir dize olarak geri veritabanında ve depolar yeniden biçimlendirir (ki ayrı bir bakım görevi olarak, ya da sadece veri ile çalışmaya başlamadan önce ya) senin işinden önce bir temizleme işi çalıştırmak demek eğer o değil en iyi biçimi.

Iki hafta önce veritabanında tarihinden bulma hedef hakkında ayrı bir soru. Nasıl biliyor musunuz, bir gün veya bir ay önce kullanıcı girişi, her iki değerin 12 daha az olur? 1/5/06 gibi bir tarih için, nasıl bir kullanıcı 1 May veya 5 Ocak demek olmadığını biliyor musunuz? Bunu çözmek, ya da 14 gün çıkarmak için önce, en azından, bu konuda bir karar vermek zorunda düşünüyorum.