Regex uzmanları!

5 Cevap php

Ben gibi bir dize var ...

"labour 18909, liberals 12,365,conservatives 14,720"

I kolayca numaraları çekin böylece ... ve ben herhangi binlerce ayırıcılar kurtulabilirsiniz bir regex istiyorum. Ya da bana böyle bir derli toplu bir dizi verebilir hatta bir regex:

(labour => 18909, liberals => 12365, conservatives => 14720)

Oh i Regexes anlamaya zaman olsaydı! Belki mmm, bir tuvalet kitap olarak bir tane alacağım.

5 Cevap

İki astar. Ayrıca Bağımsızlar alacak:

preg_match_all('/([a-zA-Z]+)\s*([\d,]+)(?:,|$)/', $str, $matches);
$totals = array_combine($matches[1], $matches[2]);

/* total:
Array
(
    [labour] => 18909
    [liberals] => 12,365
    [conservatives] => 14,720
)
*/

Sen bir arama yapmak ve bu sed gibi yerini alabilir:

> echo '"labour 18909, liberals 12,365,conservatives 14,720"'
    | sed -r -e 's/([0-9]),([0-9]{3})/\1\2/g'
"labour 18909, liberals 12365,conservatives 14720"

Ben PHP sözdizimi olurdu ne tamamen emin değilim ama temelde bir rakam (X), bir virgül, ve diğer üç basamak (Y) oluşan bir model alır ve sadece XY biraz onları değiştirir.

What you want seems to be to remove commas only if they are surrounded by digits. Sorry, I don't know the particulars of PHP regex syntax, but a couple of more abstract examples are

str.replace("(\d+),(\d+)", "$1$2")
s/([0-9]+),([0-9]+)/\1\2/g

Bunların hepsi doğru numaralarını almak istiyorum, ama aynı zamanda "2,41,11" olarak gerçekten uygun değildi şey, alacağı

Peki, şu normal ifadeyi kullanarak size diğerlerinden numaralarını ayırabilirsiniz:

labour\s*([\d,.]+),\s*liberals\s*([\d,.]+),\s*conservatives\s*([\d,.]+)

Sonuçta, bir dizi açıkça artık hiçbir rakam şöyle bir noktada biter. Daha sonra değerlerden virgül kaldırılması ile devam edebilirsiniz.

PowerShell demo (yoğunlaştırılmış biraz, özür dilerim):

PS Home:\> $s -match 'labour\s*(?<labour>[\d,.]+),\s*liberals\s*(?<liberals>[\d,.]+),\s*conservatives\s*(?<conservatives>[\d,.]+)' |
               Out-Null
PS Home:\> "Labour: {0}`nLiberals: {1}`nConservatives: {2}" -f `
           ($Matches['labour'],$Matches['liberals'],$Matches['conservatives'] |
               foreach { $_ -replace ',' })

Labour: 18909
Liberals: 12365
Conservatives: 14720

Bir önceki hayatında, ben işlemek için gün alma kayıtları milyonlarca 100'ün vardı dışında, bu gibi veri işleme bir sürü iş yaptım.

Ben her zaman bu stratejiyi takip etmek akıllıca bulundu

  1. Size veri bilin

    . Müşteri her zaman kendi veri, mükemmel iyi oluşturulmuş ve doğru diyecek

    . Bu her zaman dodo kıç dumanı tüten bir kazık olduğunu.

  2. Veriler için kurallar tanımlamak, bazen veri değil ne tanımlamak daha kolaydır

  3. Bir regex hatta makro aramayı kullanın ve veri kurallarını tatili nerede bulmak içinde ve editör değiştirin

  4. Onarım, yeni veri setleri istemek, ıskarta veri

  5. Veri temiz kadar 3. ve 4. adımları tekrarlayın

  6. Şimdi veri biçimi hakkında düşünmek, regex eşleşen bazı verilerin basit manipülasyon tarafından basitleştirilmiş olabilir

    . Örneğin durumda, bir tek virgül ile birden fazla beyaz boşluk ve ardından bir virgül yerine

    . Sonra sayılarla çevrili her virgül şerit

    . (tek bir beyaz boşluk bırakın) birden fazla beyaz boşluk şerit

    . hemen önce ve alfa karakter beyaz boşluk şerit

  7. Bu yeni veri seti için kurallar tanımlamak ve emin temiz hale

    . Şimdi bu sayısal verilere aralık denetimini ekleyebilirsiniz

    . daha karmaşık kurallar

  8. Şimdi veri "emek 18909, 12365 liberaller, muhafazakarlar 14720" gibi görünüyor

  9. Eğer bu yeni veri seti için aracı ithal İnşa (kolay bit)

  10. Müşteri onlar şu anda ihtiyacınız basit bir değişiklik veya sadece bu ekstra biraz isteyeceksiniz olarak emin 1. .. 9 için tekrarlanabilir bir sisteme sahip olun.