C #: vymezují-li řetězec jako tento vzor; možné regex

hlasů
2

Vezměme si řetězec, který vypadá takto:

RR1 S5 C92

Tento venkovský trasa adresu pro doručování out-of-město mail: Rural Route, UNESCO, prostoru. Každé písmeno je následovaný číslem a mezerou. Obvykle jeden až tři číslice dlouho, ale člověk nikdy neví, kolik čísel by to mohlo být! V případě, že uživatel je líný, mohou zadali nula, jedna nebo mnoho mezer.

Otázka: Co regex byste použít k určení, zda daný řetězec odpovídá tento vzor?

Jeho použití by bylo něco jako toto:

string ruralPattern; //a regex pattern here
bool isRural = Regex.Match(someString, ruralPattern);

Aktualizace: Děkuji vám za vaše návrhy! Výkon a použití budou v rámci statické metody v sestavě, které mají být volána z webové služby. Řetězce jsou porovnány s tímto vzorem bude maximálně 50 znaků. Metoda se bude jmenovat zhruba každých 5 sekund. Nějaké návrhy na zachováním statické? Vysoce ceněné!

Položena 26/08/2009 v 23:11
zdroj uživatelem
V jiných jazycích...                            


4 odpovědí

hlasů
9

To by mělo fungovat:

^[Rr][Rr]\d+ *[Ss]\d+ *[Cc]\d+$

nebo podle jiných komentář

^[Rr][Rr][0-9]+ *[Ss][0-9]+ *[Cc][0-9]+$

Co to všechno znamená:

  • ^ - začátek řetězce
  • [Rr] - další znak musí být R nebo R
  • [Rr] - další znak musí být R nebo R
  • \ D + nebo [0-9] + - Další část musí být 1 nebo více číslic
  • (Mezera) * - umožňují 0 nebo více mezerami
  • [Ss] - další znak musí být S nebo S
  • \ D + nebo [0-9] + - Další část musí být 1 nebo více číslic
  • (Mezera) * - umožňují 0 nebo více mezerami
  • [Cc] - další znak musí být Cnebo
  • \ D + nebo [0-9] + - Další část musí být 1 nebo více číslic
  • $ - konec provázku

Tam by mohlo být více elegantní řešení, ale to je docela dobře čitelný.

Edit: Aktualizováno zahrnout vstupu z některých komentářů

Odpovězeno 26/08/2009 v 23:12
zdroj uživatelem

hlasů
3

Co takhle...

someString = someString.Trim(); // eliminate leading/trailing whitespace
bool isRural = Regex.Match(
   someString,
   @"^rr\d+\s*s\d+\s*c\d+$",
   RegexOptions.IgnoreCase);

Tím odpadá velká písmena / malá písmena přepnutí do vzoru a používá \s, aby jakékoliv (non-přechod na nový řádek) prázdný znak (např kartách). Pokud se chcete prostory teprve pak '\s'by měl být změněn ' '.

Odpovězeno 27/08/2009 v 00:03
zdroj uživatelem

hlasů
1

Pojďme uklidit z následujících předpokladů:

  1. Existují tři sekce na provázku.
  2. Sekce 1 vždy začínají RR velká či malá písmena a končí s jedním nebo více desetinných míst.
  3. část 2 vždy začínají S velká nebo malá a končí s jedním nebo více desetinných míst.
  4. část 3 vždy začínají C horní nebo dolní a končí s jedním nebo více desetinných míst.

Pro jednoduchost, následující bude stačit.

[Rr][Rr][0-9]+[ ]+[Ss][0-9]+[ ]+[Cc][0-9]+
  1. [Rr] znamená přesně jednu abeceda R, malá nebo velká písmena.
  2. [0-9] znamená přesně jedno desetinné číslo.
  3. [0-9] + znamená alespoň jeden, nebo více, desítkové číslice.
  4. [] + Znamená alespoň jeden, nebo více, mezery.

Nicméně, být užitečný, za normálních okolností, pokud používáte regulární výrazy, bychom také detekovat jednotlivé úseky využít schopnosti odpovídající, kteří nám pomohou přiřadit jednotlivé hodnoty sekce na svých / jednotlivých proměnných.

Proto následující regex je užitečnější.

([Rr][Rr][0-9]+)[ ]+([Ss][0-9]+)[ ]+([Cc][0-9]+)

Pojďme platí, že regulární výraz na řetězec

string inputstr = "Holy Cow RR12 S53 C21";

To je to, co by váš regex dohazovač, abyste věděli:

start pos=9, end pos=21
Group(0) = Rr12 S53 C21
Group(1) = Rr12
Group(2) = S53
Group(3) = C21

K dispozici jsou tři páry eliptických / kulatých závorkách. Každý pár je část řetězce, který regex překladač volá skupinu.

Regex kompilátor by volal zápas

  1. celé uzavřeno řetězec jako skupina 0
  2. venkovské cesta jako skupina 1,
  3. místo jako skupina 2 a
  4. prostor jako skupina 3.

Samozřejmě, že skupiny 1, 2 a 3 setkat zápasů, a to pouze v případě, skupina 0 obsahuje shodu.

Z tohoto důvodu váš algoritmus by zneužít, že s tímto pseudocode

string postalstr, rroute, site, compart;
if (match.group(0)!=null)
{
  int start = match.start(0);
  int end = match.end(0);
  postalstr = inputstr.substring(start, end);

  start = match.start(1);
  end = match.end(1);
  rroute = inputstr.substring(start, end);

  start = match.start(2);
  end = match.end(2);
  site = inputstr.substring(start, end);

  start = match.start(3);
  end = match.end(3);
  compart = inputstr.substring(start, end);
}

Kromě toho možná budete chtít vstoupit do databázové tabulky se sloupci: rr, místa, Compart, ale chcete pouze číslice zadána bez abeced „RR“, „S“ nebo „C“. To by byl regex s vnořené seskupení použít.

([Rr][Rr]([0-9]+))[ ]+([Ss]([0-9]+))[ ]+([Cc]([0-9]+))

A dohazovač dáme vám vědět, následující dojde ke shodě pro skupinu 0:

start=9, end=21
Group(0) = Rr12 S53 C21
Group(1) = Rr12
Group(2) = 12
Group(3) = S53
Group(4) = 53
Group(5) = C21
Group(6) = 21
Odpovězeno 27/08/2009 v 01:54
zdroj uživatelem

hlasů
0

S pozdravem: Pokud budete používat tento RegEx testovat velké množství dat, je nejlepší by bylo říci .NET ji předkompilovat - to budou sestaveny do IL a poskytnout zvýšení výkonu, spíše než jednoduše interpretovat RegEx vzor pokaždé. Specifikovat jako statický člen na cokoliv Třída obsahuje svoji metodu, jako tak:

private static Regex re = new Regex("pattern", RegexOptions.Compiled | RegexOptions.IgnoreCase);

... a způsob, jak otestovat, zda řetězec odpovídá vzoru je ...

bool matchesString = re.IsMatch("string");

Hodně štěstí.

Odpovězeno 27/08/2009 v 03:08
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more