Avatar billede jespera Nybegynder
25. maj 2005 - 19:12 Der er 17 kommentarer og
2 løsninger

Replace en streng kun en gang selvom den forekommer flere gange

Hej,

Når man bruger minString.Replace("oldString","newString"); så erstatter den alle tilfælde.

Findes der en smart måde så man kun erstatter den første den finder og ikke alle de andre selvom oldString forekommer flere gange...
Avatar billede arne_v Ekspert
25. maj 2005 - 19:21 #1
jeg ved ikke om det kan gøres smartere men:

        public static string ReplaceOne(string s, string fnd, string rpl)
        {
            int ix = s.IndexOf(fnd);
            if(ix >= 0)
            {
                return s.Substring(0, ix) + rpl + s.Substring(ix + fnd.Length);
            }
            else
            {
                return s;
            }
        }
Avatar billede nielle Nybegynder
25. maj 2005 - 19:51 #2
Jeg ved ikke om man kan påstå at det er smartere, men det kan også løses vha. regulære udtryk:

using System;
using System.Text.RegularExpressions;

namespace Eksperten
{
    class Class1
    {
        [STAThread]
        static void Main(string[] args)
        {
            string Source = "Det er kun den første forekomst af ordet Alpha som skal erstattes med Beta - ikke den anden forekomst af Alpha. Nemlig, ja!";
            string Pattern = "(.*?)Alpha(.*)";
            Regex RE = new Regex(Pattern);
            string Target = RE.Replace(Source, @"$1Beta$2");

            Console.WriteLine(Source);
            Console.WriteLine(Target);
        }
    }
}
Avatar billede jespera Nybegynder
25. maj 2005 - 20:30 #3
ok, men hvorfor er den static og hvad er det lige der bliver sub ud....evt en lille breif forklaring....
Avatar billede arne_v Ekspert
25. maj 2005 - 20:33 #4
minString = ReplaceOne(minString, "oldString","newString");
Avatar billede jespera Nybegynder
25. maj 2005 - 20:34 #5
okay samme tidspunkt for en kommentar :-)
Avatar billede jespera Nybegynder
25. maj 2005 - 20:49 #6
Jeg forstå ikke lige hvordan den der Substring fungerer.....

kan du ikke forklare den sætning.......

content.Substring(0, ix) + newUrl + content.Substring(ix + orginalUrl.Length)
Avatar billede nielle Nybegynder
25. maj 2005 - 20:57 #7
"static" har i dette tilfælde intet som helst at gøre med løsningen på problemet. Main-metoden skal simpelthen bare altid være erklæret som static. :^)

Det er den første forekomst af ordet "Alpha" som bliver erstattet med ordet "Beta" - den anden forekomst bliver ved med at være "Alpha". Prøv at kør koden så ser du det selv.

Ok, en meget kort tutorial om regulære udtryk:

Det centrale i er RegExp er et "mønster" - det er dette som jeg har i min variabel Pattern. I dette tilfælde er Pattern altså:

(.*?)Alpha(.*)

Sætningen:

Regex RE = new Regex(Pattern);

- opretter et RegExp baseret på dette monster.

Når noget er omgivet med parenteser så er det fordi vi vil huske det til senere. I dette tilfælde er det altså noget før ordet "Alpha", samt noget efter det, som vi vil huske. Mere om det der står inden i parenteserne lige om lidt.

Senere når vi skal huske det igen så huskes værdien fra den første parentes som $1 og den anden parentes som $2. Der er disse to som du ser i 2. argument i Replace() funktionen.

string Target = RE.Replace(Source, @"$1Beta$2");

(Tegnet '@' kan i øvrigt slettes igen - det var en fejl.)

Replac'en fungere i dette tilfælde sådan her.

"Den nye streng skal være lig med det som vi huskede fra *før* Alpha + ordet Beta + det vi huskede fra *efter* Alpha."

Tilbage til det som stod indenfor i parenteserne: ".*?" og ".*".

Den sidste først: Et punktum betyder "et vilkårligt tegn" og en asterisk ('*') betyder "0-eller-flere". Derfor betyder ".*" det samme som "0-eller-flere-vilkårlige-tegn".

Normalt er ".*" delmønsteret "grådigt" i den forstand at det forsøger at matche så meget som det overhovedet kan. Hvis mit mønster havde set sådan her ud:

(.*)Alpha(.*)

- ville den første parentes have forsøgt at matche alt det den kunne og derfor havde den husket alt op til Alpha nr. 2. Vil ville imidlertid kun hvad den til at matche alt på til før det første Alpha! Derfor fortæller vi den at den ikke skal være grådig - at den skal være "doven" ("lazy"). Det er det som spørgsmålstegnet i det første delmønster står for.

Jeg håber at det gav lidt mening for dig?
Avatar billede jespera Nybegynder
25. maj 2005 - 21:04 #8
arhh super cool forklaring......

arne_v vil du evt hurtigt forklare hvad der sker i:
content.Substring(0, ix) + newUrl + content.Substring(ix + orginalUrl.Length)

Jeg smækker lige nogle flere point oven i hatten....super med en så god en forklaring niellen.....
Avatar billede arne_v Ekspert
25. maj 2005 - 21:05 #9
substring tager en del af en streng

content.Substring(0, ix) + newUrl + content.Substring(ix + orginalUrl.Length)

content del fra start til start på det fundne
+
erstatningen
+
content del fra slut på det fundne (=start på det fundne + længde af de fundne)
Avatar billede nielle Nybegynder
25. maj 2005 - 21:05 #10
Nå, det var da vist ikke mig som blev spurgt. :^)

Anyways, her er RegExp-versionen af Arne_v's ReplaceOne:

using System;
using System.Text.RegularExpressions;

namespace Eksperten
{
    class Class1
    {
        [STAThread]
        static void Main(string[] args)
        {
            string Source = "Det er kun den første forekomst af ordet Alpha som skal erstattes med Beta - ikke den anden forekomst af Alpha. Nemlig, ja!";
           
            string Target = ReplaceOne(Source, "Alpha", "Beta");

            Console.WriteLine(Source);
            Console.WriteLine(Target);
        }

        public static string ReplaceOne(string s, string fnd, string rpl)
        {
            string OldPattern = string.Format("(.*?){0}(.*)", fnd);
            string NewPattern = string.Format("$1{0}$2", rpl);

            Regex RE = new Regex(OldPattern);
            return RE.Replace(s, NewPattern);
        }
    }
}
Avatar billede jespera Nybegynder
25. maj 2005 - 21:16 #11
arne_v>>

Jamen substring trække den ikke noget ud af content...??

alts¨å....

1) content del fra start til start på det fundne
+
2)erstatningen
+
3)content del fra slut på det fundne (=start på det fundne + længde af de fundne)


1 ) Så læser den fra 0-10
2 ) så erstatningen ind fra plads 10 og f.eks. 20 frem
3 ) og så taber jeg altså tråden

Gab jeg er håbeløs.......
Avatar billede arne_v Ekspert
25. maj 2005 - 21:19 #12
content = "abcdefghi"
vi vil erstatte "cde" med "xyzw"
ix bliver så 2
content.Substring(0, ix) er "ab"
newUrl er "xyzw"
content.Substring(ix + orginalUrl.Length) er "fghi"
så resultatet blivet "abxyzwfghi"
Avatar billede jespera Nybegynder
25. maj 2005 - 21:30 #13
Jamen der er noget jeg ikke forstå så......

1 ) man har ab
2 ) så lægger man xyzw til ab så er streng vel abxyzw
3 ) så nu er den abxyzw, men så siger du så content.Substring(ix + orginalUrl.Length) dvs. 2+hele strengen så burden den da starte efter ab igen ? eller står man et andet sted i strengen (sorf of curser) og hvordan ved den det
Avatar billede arne_v Ekspert
25. maj 2005 - 21:33 #14
content = content.Substring(0, ix) + newUrl + content.Substring(ix + orginalUrl.Length);

er faktisk:

temp = content.Substring(0, ix) + newUrl;
content = temp + content.Substring(ix + orginalUrl.Length)

den assigner først over i content til sidst
Avatar billede jespera Nybegynder
25. maj 2005 - 21:44 #15
nå for pokker.........

Gab det er da lidt tricky, den er vist ikke rigtigt landet på øverste etage hos mig endnu altså det der med substring og hvornår det trækkes ud...........
Avatar billede jespera Nybegynder
25. maj 2005 - 23:49 #16
nå men ligger i ikke et svar, begge to...............

takker :-)
Avatar billede nielle Nybegynder
26. maj 2005 - 06:24 #17
Svar :^)
Avatar billede arne_v Ekspert
26. maj 2005 - 07:10 #18
svar
Avatar billede jespera Nybegynder
31. maj 2005 - 11:50 #19
Tak for hjælpen i 2, helt perfekt. Jeg brugte Arne_v løsning..... :-)
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
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

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