Avatar billede CodingJoe Nybegynder
02. november 2012 - 09:40 Der er 15 kommentarer og
1 løsning

Regexp

Jeg er ekstrem dårlig til regexp.

Mit behov er at fjerne noget tekst imellem nogle særlige tegn.

1. Fjerne karakterer imellem '<' og ':' (Hvor ':' er inkluderet i fjernelsen, '<' skal bibeholdes)

2. Fjerne karakterer mellem '/' og ':' (Begge tegn inkluderet i fjernelsen).

2. Fjerne karakterer imellem 'xmlns:' og '=', hvor 'xmlns' og '=' bibeholdes.

Jeg forsøger selv imens, men er nysgerrig for forslag.
Avatar billede johny Nybegynder
02. november 2012 - 10:18 #1
Er performance vigtig? For når jeg ikke ved mere om det end hvad du skriver, er det sikreste at bruge en "lazy quantifier", men det går ud over performance, men her er et regex der opfylder dine umiddelbare krav:

(?<=<).+?:|/.+?:|(?<=xmlns):.+?(?==)

Vil du gerne have en lidt mere forståelig variant er den her med kommentarerer (som også kan køres i stedet for ovenstående, hvis du slår "Ignore Whitespace" til):

#regex start:
#part 1:
(?<=<) #Match '<', men inkluder det ikke.
.+?: #Match så lidt som muligt, indtil du når til ':'.

#part 2:
|
/.+?: #Match '/ ' efterfulgt af så lidt som muligt, indtil du når til ':'.

#part 3:
|
(?<=xmlns) #Match 'xmlns', men inkluder det ikke.
:.+? #Match ':' efterfulgt af så lidt som muligt.
(?==) #Match '=' men inkluder det ikke.
#regex slut
Avatar billede CodingJoe Nybegynder
02. november 2012 - 10:25 #2
Det ser lækkert ud. Jeg har ikke prøvet det endnu. Det skal helst performe godt, det er en meget dum rettelse, og går i virkeligheden på at servicere nogle kunder, der ikke kan modtaget namespace prefixes på det xml vi sender. Derfor skal jeg bare fjerne namespace prefixes, og det skal gå relativt hurtigt. :)
Avatar billede CodingJoe Nybegynder
02. november 2012 - 10:25 #3
Der er iøvrigt ingen whitespaces imellem.
Avatar billede CodingJoe Nybegynder
02. november 2012 - 10:32 #4
Min xml streng ser således ud:
<?xml version="1.0" encoding="utf-8"?><ns0:MineXmlData xmlns:ns0="http://www.google.com/schemas/minedata"><Personer><Personer></ns0:MineXmlData>

og resultatet:

<?xml version="1.0" encoding="utf-8"?><MineXmlData xmlns="http://www.google.com/schemas/minedata"><Personer><Personer></MineXmlData>
Avatar billede CodingJoe Nybegynder
02. november 2012 - 10:35 #5
Det kunne man vist ikke skrive her...prøver igen:

<?xml version="1.0" encoding="utf-8"?><ns0:MineXmlData xmlns:ns0="google/schemas/minedata"><Personer><Personer></ns0:MineXmlData>

resultatet:

<?xml version="1.0" encoding="utf-8"?><MineXmlData xmlns="google/schemas/minedata"><Personer><Personer></MineXmlData>


Der kan stå en http addresse i xmlns, som jeg blev nødt til at fjerne herinde.
Avatar billede CodingJoe Nybegynder
02. november 2012 - 10:52 #6
Har lige prøvet dit forslag, men den klipper for meget væk :(

Istedet for:
"<?xml version=\"1.0\" encoding=\"utf-8\"?><ns0:MineXmlData xmlns:ns0=\"http:/ /www.google.com/schemas/minedata\"><Personer><Personer></ns0:MineXmlData>"

får jeg:
"<MineXmlData xmlns="http:MineXmlData>"

Bemærk jeg har sat mellemrum mellem '/ /' i http adressen, da det bliver formateret til et link herinde.
Avatar billede CodingJoe Nybegynder
02. november 2012 - 11:31 #7
Jeg kan se at mine første regelsæts forklaringer, faktisk ikke var nok, da jeg sidder selv og fanger små undtagelser.

Min xml streng ser således ud:
<?xml version="1.0" encoding="utf-8"?><ns0:MineXmlData xmlns:ns0="http:/ /google/schemas/minedata"><ns0:Personer></ns0:Personer></ns0:MineXmlData>

Rsulatatet jeg prøver at opnå er følgende:

<?xml version="1.0" encoding="utf-8"?><MineXmlData xmlns="http:/ /google/schemas/minedata"><Personer><Personer></MineXmlData>
Avatar billede CodingJoe Nybegynder
02. november 2012 - 12:00 #8
(?<=<).+.\[a-Z]:|(?=</).+.\[a-Z]:|(?<=xmlns):.+?(?==)

Denne giver mig:
<?xml version="1.0" encoding="utf-8"?><ns0:MineXmlData xmlns="http:/ /google/schemas/minedata"><ns0:Personer></ns0:Personer></ns0:MineXmlData>

Så den retter fint xmlns, men mangler, det der står i start og slut tags som prefixes.
Avatar billede CodingJoe Nybegynder
02. november 2012 - 14:48 #9
Følgende er ved explicit angivelse af namespace prefix:
(?<=<)ns0:|(?<=)/ns0:+|(?<=xmlns):.+?(?==)

Jeg er ikke helt i land, men håber jeg kan få sat det sidste på plads. :S
Avatar billede johny Nybegynder
02. november 2012 - 15:34 #10
jamen hvis der ikke må være mellemrum bliver det hele væsentligt lettere. :) Der må vel heller ikke være '<' og '>' ?

prøv den her:

(?<=<)[^"\s<>]+:|/[^"\s<>]+:|(?<=xmlns):[^"\s<>]+(?==)
Avatar billede johny Nybegynder
02. november 2012 - 15:40 #11
(i stedet for at tage alt ind til næste tegn, så tager jeg nu alt det jeg kan, men kun hvor der ikke er tale om apostroffer, whitespaces, samt tegnene '>' og '<'.)
Avatar billede CodingJoe Nybegynder
02. november 2012 - 16:21 #12
Den virker fint i Expresso, som jeg bruger til Regexp, men ved tildeling af i .net regexp brokker den sig over formatet. Har forsøgt at escape " men det hjælper ikke :(
Avatar billede CodingJoe Nybegynder
02. november 2012 - 17:02 #13
Jeg har fået lavet min egen varian:

(?<=<)[a-zA-Z0-9]+:|(?<=/)[a-zA-Z0-9]+:+|(?<=xmlns):.+?(?==)

Kan du evt. reviewe den?

Jeg giver points herefter :)
Avatar billede johny Nybegynder
02. november 2012 - 17:47 #14
Jeg går ikke så meget op i points, så det skal du ikke tænke på. :)

Hvilken fejl får du præcist? For det er ikke bare fordi du mangler @ foran dit regexp pattern:
Regex.Replace(@"(?<=<)[^""\s<>]+:|/[^""\s<>]+:|(?<=xmlns):[^""\s<>]+(?==)", "");

Det skal lige siges, at det er bedre at lave en instans af Regex hvor du bruger "Compiled" option'en.

Angående din, så vil jeg tro den er ok, medmindre du f.eks. laver namespaces med '_' i (det kan jeg ikke lige huske på stående fod huske om XML tillader). Derudover er der også lige sneget sig to fejl ind:

(?<=<)[a-zA-Z0-9]+:|(?<=/)[a-zA-Z0-9]+:|(?<=xmlns):[a-zA-Z0-9]+(?==)

(fjernede et plus der ikke var der [som heller ikke rigtig gjorde noget, da det kun ville få effekt ved invalid xml], og så satte "[a-zA-Z0-9]+" ind i stedet for et ".+?")
Avatar billede CodingJoe Nybegynder
02. november 2012 - 18:37 #15
Mange tak for inputs :)

Jeg prøvede at sætte verbatim @ foran, men det hjalp ikke, så derfor begyndte jeg med min egen udgave.

Jeg kan lige gøre endnu et forsøg herhjemme, men ellers vil jeg rette min egen til i henhold til dine forslag.
Avatar billede johny Nybegynder
02. november 2012 - 19:51 #16
Hvis du vil være lidt mere sikker på at at det går godt, kan du jo evt. lige bygge din regex op, efterhånden som du opdager at der skal tilføjes flere karakterer, hvis det er tilfældet:

string allowedChars = "[a-zA-Z0-9]";

string pattern = String.Format(@"(?<=<){0}:|(?<=/){0}:|(?<=xmlns):{0}(?==)", allowedChars + "+");

var regex = new Regex(pattern, RegexOptions.Compiled);
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester