Permalänk

Regex problem i C#.net

Har stött på problem i skapandet av några Regex i C#

Det jag vill göra är att kontrollera om en sträng uppfyller en specifik Regex. Problemet jag har är att den Regex jag använder mig av kan alltid uppfyllas av en del av strängen. Nedan följer koden:

public const string NonHyphenSpecialChar = @\.|,|\||\?; public const string Hyphen = "-"; public const string ExtendedSpecialChar = @!|@|#|$|%|\^|&|\*|=|_|\+|[|]|{|}|\|;|<|>|~|\|; public const string NumericChar = "[0-9]"; public const string AlfabeticUpperCase = "[A-Z]"; public const string AlfabeticLowerCase = "[a-z]"; public const string SpecialCharecter = NonHyphenSpecialChar + "|" + Hyphen; public const string DataCode = SingleDataCodeCharacter + "|(" + FirstLastDataCodeChar + DataCodeChar + "*" + FirstLastDataCodeChar + ")"; public const string DataCodeChar = FirstLastDataCodeChar + "|" + BlankChar; public const string FirstLastDataCodeChar = SingleDataCodeCharacter + "|" + Hyphen; public const string SingleDataCodeCharacter = AlfabeticUpperCase + "|" + AlfabeticLowerCase + "|" + NumericChar + "|" + NonHyphenSpecialChar + "|" + ExtendedSpecialChar; public static void Main(string[] args) { string test = "d9s"; Regex r = new Regex(@^ + DataCode + @$); Match m = r.Match(test); Console.WriteLine("m: " + m.ToString()); Console.WriteLine("t: " + test); Console.Read(); }

Matchningen blir då endast på 'd' i strängen d9s. Det jag vill göra är att den kollar hela strängen "d9s" emot DataCode och endast matchar den om HELA strängen uppfyller RegExen. Jag vet att DataCode kan uppfyllas av endast en singleDataCodeCharacter men om strängen består av fler tecken vill jag att den kollar emot FirstLastDataCodeChar DataCodeChar * FirstLastDataCodeChar. Hur gör jag detta?

Visa signatur

Bison: You have made me a very happy man.
Colonel William F. Guile: And next, I'll make you a dead one.

Permalänk
Medlem

Inget svar på din fråga eftersom jag aldrig orkar tänka på regex förutom när jag själv tvingas till att göra nåt regex.

Men ett tips är att ladda ner http://www.ultrapico.com/Expresso.htm
Jag tycker det är ett riktigt grymt program för att ta fram och testa regex.

Visa signatur

EPoX 8RDA+, XP2500+, 2x256Mb PC3200 (DualCh), Club3D 9800PRO, Seagate 7200.7 160Gb 8Mb Limited edition

Permalänk
Medlem
Skrivet av SlaktarFar:

Har stött på problem i skapandet av några Regex i C#

Det jag vill göra är att kontrollera om en sträng uppfyller en specifik Regex. Problemet jag har är att den Regex jag använder mig av kan alltid uppfyllas av en del av strängen. Nedan följer koden:

public const string NonHyphenSpecialChar = @\.|,|\||\?; public const string Hyphen = "-"; public const string ExtendedSpecialChar = @!|@|#|$|%|\^|&|\*|=|_|\+|[|]|{|}|\|;|<|>|~|\|; public const string NumericChar = "[0-9]"; public const string AlfabeticUpperCase = "[A-Z]"; public const string AlfabeticLowerCase = "[a-z]"; public const string SpecialCharecter = NonHyphenSpecialChar + "|" + Hyphen; public const string DataCode = SingleDataCodeCharacter + "|(" + FirstLastDataCodeChar + DataCodeChar + "*" + FirstLastDataCodeChar + ")"; public const string DataCodeChar = FirstLastDataCodeChar + "|" + BlankChar; public const string FirstLastDataCodeChar = SingleDataCodeCharacter + "|" + Hyphen; public const string SingleDataCodeCharacter = AlfabeticUpperCase + "|" + AlfabeticLowerCase + "|" + NumericChar + "|" + NonHyphenSpecialChar + "|" + ExtendedSpecialChar; public static void Main(string[] args) { string test = "d9s"; Regex r = new Regex(@^ + DataCode + @$); Match m = r.Match(test); Console.WriteLine("m: " + m.ToString()); Console.WriteLine("t: " + test); Console.Read(); }

Matchningen blir då endast på 'd' i strängen d9s. Det jag vill göra är att den kollar hela strängen "d9s" emot DataCode och endast matchar den om HELA strängen uppfyller RegExen. Jag vet att DataCode kan uppfyllas av endast en singleDataCodeCharacter men om strängen består av fler tecken vill jag att den kollar emot FirstLastDataCodeChar DataCodeChar * FirstLastDataCodeChar. Hur gör jag detta?

Kan du inte göra en if-sats som kollar längden på strängen och sen stoppa in rätt regexp-uttryck?

Visa signatur

ηλί, ηλί, λαμά σαβαχθανί!?

Permalänk
Skrivet av Leedow:

Kan du inte göra en if-sats som kollar längden på strängen och sen stoppa in rätt regexp-uttryck?

Tyvärr inte då jag har flera andra regexp-uttryck som använder sig av DataCode. Problemet jag har med DataCode har jag även med andra regexp-utryck som inte går att fixa genom att kolla längden.

Har suttit lite i Expresso och fått fram ^(([a-zA-Z0-9])|([a-zA-Z0-9][a-zA-Z0-9]*[a-zA-Z0-9]))$ som gör som jag vill, dock har jag problem med att anpassa detta till min kod. Ändra min kod till:

DataCode = "^((" + SingleDataCodeCharacter + ")|(" + FirstLastDataCodeChar + DataCodeChar + "*" + FirstLastDataCodeChar + "))$";

Men då accepterar den bara strängar som är ett tecken långt =/.

Visa signatur

Bison: You have made me a very happy man.
Colonel William F. Guile: And next, I'll make you a dead one.

Permalänk
Medlem

Jag vet inte riktigt om jag förstått dig rätt, men det här bör fungera....

(d9.*a)|(d{1})$

då matchar den antingen att datakoden måste börja med d9 sen ett antal tecken för att sen avslutas med a, eller att den bara är d... Somsagt, jag vet inte om det är så du tänkt dig men men...

Permalänk
Medlem
Skrivet av SlaktarFar:

Tyvärr inte då jag har flera andra regexp-uttryck som använder sig av DataCode. Problemet jag har med DataCode har jag även med andra regexp-utryck som inte går att fixa genom att kolla längden.

Har suttit lite i Expresso och fått fram ^(([a-zA-Z0-9])|([a-zA-Z0-9][a-zA-Z0-9]*[a-zA-Z0-9]))$ som gör som jag vill, dock har jag problem med att anpassa detta till min kod. Ändra min kod till:

DataCode = "^((" + SingleDataCodeCharacter + ")|(" + FirstLastDataCodeChar + DataCodeChar + "*" + FirstLastDataCodeChar + "))$";

Men då accepterar den bara strängar som är ett tecken långt =/.

Enligt mig så använder du "^" och "$" på fel sätt. När du har två eller fler uttryck i din regexp så behöver du det där för varje uttryck.
Exempel:
^[a-z]|[a-z][A-Z]$
ger inte samma resultat som
^[a-z]$|^[a-z][A-Z]$

Om du hade lyckats klämma in "^" och "$" på varje uttryck så hade det fungerat.

Personligen så hade jag gjort en RegexpHelper-klass där man kan hämta rätt dynamisk regular expression.
Ibland vill man ha "^" och "$" på varje uttryck, ibland vill man ha det runt hela regexpen, etc.

Men det kanske är för stort steg att ta nu, baserat på hur långt du redan har använt det du har?

Visa signatur

ηλί, ηλί, λαμά σαβαχθανί!?

Permalänk
Medlem
Skrivet av thrawn:

Jag vet inte riktigt om jag förstått dig rätt, men det här bör fungera....

(d9.*a)|(d{1})$

då matchar den antingen att datakoden måste börja med d9 sen ett antal tecken för att sen avslutas med a, eller att den bara är d... Somsagt, jag vet inte om det är så du tänkt dig men men...

Godmorgon på dig.

Varför man väljer regexp är för att det finns ett bestämt mönster av tecken och ja, det är lite svårt att göra regexp när man inte vet kraven.

Visa signatur

ηλί, ηλί, λαμά σαβαχθανί!?

Permalänk
Skrivet av Leedow:

Enligt mig så använder du "^" och "$" på fel sätt. När du har två eller fler uttryck i din regexp så behöver du det där för varje uttryck.
Exempel:
^[a-z]|[a-z][A-Z]$
ger inte samma resultat som
^[a-z]$|^[a-z][A-Z]$

Om du hade lyckats klämma in "^" och "$" på varje uttryck så hade det fungerat.

Personligen så hade jag gjort en RegexpHelper-klass där man kan hämta rätt dynamisk regular expression.
Ibland vill man ha "^" och "$" på varje uttryck, ibland vill man ha det runt hela regexpen, etc.

Men det kanske är för stort steg att ta nu, baserat på hur långt du redan har använt det du har?

Du hade rätt jag använde '^' och '$' fel. Hade även gjort felet att jag inte hade satt "()" runt vissa sammansatta uttryck vilket gjorde att jag fick konstig resultat men nu fungerar det som det ska, tack för hjälpen!

Visa signatur

Bison: You have made me a very happy man.
Colonel William F. Guile: And next, I'll make you a dead one.

Permalänk
Medlem

Lånar tråden

Jag har en regex som kollar "^[0-9]+$" dvs bara siffror.
Men vill lägga till så den kollar om det finns max 1st "," (kommatecken)..
Får vara 0 st men inte 2 st.

Permalänk
Medlem
Skrivet av MB:

Jag har en regex som kollar "^[0-9]+$" dvs bara siffror.
Men vill lägga till så den kollar om det finns max 1st "," (kommatecken)..
Får vara 0 st men inte 2 st.

Du ska egentligen kontrollera om det är ett decimaltal?
Jag tror att jag hade kört Decimal.TryParse() eller något annat.

Hur som helst...
Kommatecknet får inte heller komma först eller sist(?)
Det finns inte alltid ett kommatecken(?)

Regex: (första) (andra) ^[0-9]+,{0,1}[0-9]+$|^[0-9]+$ Test och resultat: 123123,123123 //Match (första) 123,123123123 //Match (första) 123123, ,123123 124124 //Match (första) 1 //Match (andra) 1, ,1 Testverktyg: http://gskinner.com/RegExr/

Visa signatur

ηλί, ηλί, λαμά σαβαχθανί!?

Permalänk
Medlem

Istället för {0, 1} kan man använda ?

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem
Skrivet av Teknocide:

Istället för {0, 1} kan man använda ?

Snyggt!

Visa signatur

ηλί, ηλί, λαμά σαβαχθανί!?

Permalänk
Medlem
Skrivet av Leedow:

Du ska egentligen kontrollera om det är ett decimaltal?
Jag tror att jag hade kört Decimal.TryParse() eller något annat.

Hur som helst...
Kommatecknet får inte heller komma först eller sist(?)
Det finns inte alltid ett kommatecken(?)

Regex: (första) (andra) ^[0-9]+,{0,1}[0-9]+$|^[0-9]+$ Test och resultat: 123123,123123 //Match (första) 123,123123123 //Match (första) 123123, ,123123 124124 //Match (första) 1 //Match (andra) 1, ,1 Testverktyg: http://gskinner.com/RegExr/

Är när en användare redigerar ett fält. Då ska den säga till om fel tecken är med. Så med andra ord så funkar inte riktigt decimal.tryparse. Eller tänkte du att man körde en if-sats på om den gick igenom, annars felmeddelande?

Det du skapade var exakt det som jag behövde. Tack för hjälpen

Permalänk
Medlem
Skrivet av MB:

Är när en användare redigerar ett fält. Då ska den säga till om fel tecken är med. Så med andra ord så funkar inte riktigt decimal.tryparse. Eller tänkte du att man körde en if-sats på om den gick igenom, annars felmeddelande?

Det du skapade var exakt det som jag behövde. Tack för hjälpen

Precis.

if (Decimal.TryParse(userInputData)) { doMagic(); }

Denna lösning oändligt bättre, enligt mig.
Men det betyder inte att det du har gjort är onödigt. Du har ju lärt dig lite mer om Regex och det är väl aldrig fel?

Visa signatur

ηλί, ηλί, λαμά σαβαχθανί!?

Permalänk
Medlem

Nej nej det är inte fel! Men det är ju riktigt jobbigt.
Lite dum fråga men använder majoriteten sig av regex eller kodar man hellre?

Programmera vad fältet tillåter osv känns lite mer kraftkrävande än regex?

Ett nytt regex villkor om ni pallar?
Först vill jag ha siffror som kan skiljas med ett kommatecken, sen nya siffror, nytt kommatecken. Så man delar upp talen med kommatecken.
Tex: 233,588,121,4444 typ

Permalänk
Medlem
Skrivet av MB:

Nej nej det är inte fel! Men det är ju riktigt jobbigt.
Lite dum fråga men använder majoriteten sig av regex eller kodar man hellre?

Programmera vad fältet tillåter osv känns lite mer kraftkrävande än regex?

Ett nytt regex villkor om ni pallar?
Först vill jag ha siffror som kan skiljas med ett kommatecken, sen nya siffror, nytt kommatecken. Så man delar upp talen med kommatecken.
Tex: 233,588,121,4444 typ

Hur kan du tycka att det är jobbigare att skriva EN rad kod som för övrigt är lättläst jämfört med Regexp som består av flera rader och kräver regexp tolkning?
Jag vet inte vad majoriteten använder men jag hoppas och chansar på att det är "vanlig kod". Regexp är oftast (om inte alltid) långsammare än "vanlig kod". Regexp använder jag bara när det inte "blir enkelt" att skriva "vanlig kod", om mönstret man letar efter är för besvärligt alltså.

Regexp är ju också en form av kodning, likaså all kod runt själva regexp-uttrycket.

I ditt nya fall:
Du menar, du har en sträng som ser ut på det där viset och du vill ha ut alla tal mellan kommatecknen?

/,?([0-9]+),?/

Då måste du loopa MatchCollection från ditt Regex-objekt då varje tal kommer att vara en egen match.

Men, samma sak här.....
Strängen går att splitta på "," så får du en string-array med dina värden.

var userInputData = "111,222,333"; string[] splitResult = userInputData.Split(','); //splitResult är nu en string-array med tre strängar.

Även detta är betydligt bättre än att använda regexp... förutsatt att jag förstod ditt problem korrekt.

Visa signatur

ηλί, ηλί, λαμά σαβαχθανί!?

Permalänk
Medlem

Svarar på mig själv. Det här verkar faktiskt funka:
@^([1-9]{1}[0-9]{0,7})+((,[1-9]{1}[0-9]{0,7}){0,1})+$

Permalänk
Medlem
Skrivet av Leedow:

Hur kan du tycka att det är jobbigare att skriva EN rad kod som för övrigt är lättläst jämfört med Regexp som består av flera rader och kräver regexp tolkning?
Jag vet inte vad majoriteten använder men jag hoppas och chansar på att det är "vanlig kod". Regexp är oftast (om inte alltid) långsammare än "vanlig kod". Regexp använder jag bara när det inte "blir enkelt" att skriva "vanlig kod", om mönstret man letar efter är för besvärligt alltså.

Regexp är ju också en form av kodning, likaså all kod runt själva regexp-uttrycket.

Även detta är betydligt bättre än att använda regexp... förutsatt att jag förstod ditt problem korrekt.

Såg inte ditt svar innan jag postat. "Jobbigare", i den bemärkelsen att det är svårt.
Givigtvis så är allt svårt innan man behärskar det.

Nä men då ska jag försöka använda mig av att koda utan regex om det är möjligt.

Permalänk
Medlem
Skrivet av MB:

Såg inte ditt svar innan jag postat. "Jobbigare", i den bemärkelsen att det är svårt.
Givigtvis så är allt svårt innan man behärskar det.

Nä men då ska jag försöka använda mig av att koda utan regex om det är möjligt.

Japp, allt är svårt innan man behärskar det. Regexp är ju en lösning som fungerar väldigt lika i olika språk. Därför kanske det känns lättare att använda det. Har du använt det i andra språk innan du började med C#?

Lite rolig läsning, om inte annat:
http://www.codinghorror.com/blog/2008/06/regular-expressions-...

Visa signatur

ηλί, ηλί, λαμά σαβαχθανί!?

Permalänk
Medlem
Skrivet av Leedow:

Japp, allt är svårt innan man behärskar det. Regexp är ju en lösning som fungerar väldigt lika i olika språk. Därför kanske det känns lättare att använda det. Har du använt det i andra språk innan du började med C#?

Lite rolig läsning, om inte annat:
http://www.codinghorror.com/blog/2008/06/regular-expressions-...

Nej har aldrig använt mig utav regex.
Ska ta och kika på din länk