Avatar billede dktekno Nybegynder
17. marts 2007 - 23:13 Der er 44 kommentarer og
1 løsning

String mellem 2 andre strings

Jeg vil gerne have en funktion, f.eks.

minfunktion("blablabla","albalbalb","blablabla dette skal være mit resultat albalbalb");

Dvs. den udskriver det, der står mellem 2 andre strings.

Hvordan laver jeg det i C#?
Avatar billede arne_v Ekspert
17. marts 2007 - 23:16 #1
utestet:

string minfunktion(string s1, string s2, string s)
{
  return s.Substring(s1.Length, s.IndexOf(s2) - s1.Length);
}
Avatar billede kalp Novice
17. marts 2007 - 23:18 #2
en pænere løsning..

public string BlaBlahMetoden(string TekstEt, string TekstTo, string TekstTre)
{
    return string.Format(TekstEt + "{0}" + TekstTo, TekstTre);
}
Avatar billede kalp Novice
17. marts 2007 - 23:19 #3
Hvis du f.eks kalder den med.

BlaBlahMetoden("Hej","dig","med")

så får du "Hejmeddig" tilbage.
Avatar billede arne_v Ekspert
17. marts 2007 - 23:25 #4
lidt test siger:

        public static string MinFunktion(string s1, string s2, string s)
        {
            return s.Substring(s1.Length + 1, s.IndexOf(s2) - s1.Length - 2);
        }
Avatar billede arne_v Ekspert
17. marts 2007 - 23:27 #5
public static string MinFunktion(string s1, string s2, string s)
        {
            return s.Substring(s.IndexOf(s1) + s1.Length + 1, s.IndexOf(s2) - s.IndexOf(s1) - s1.Length - 2);
        }

hvis den skal håndtere hvor s ikke starter med s1

i begge tilfælde antager jeg mellemrum som ikke skal med i resultat
Avatar billede arne_v Ekspert
17. marts 2007 - 23:28 #6
kalps forslag er ikke en pænere løsning, men løsningen for at gå den modsatte vej
Avatar billede kalp Novice
17. marts 2007 - 23:30 #7
pænere er måske forkert sagt, men mere læsevenlig:)
Avatar billede kalp Novice
17. marts 2007 - 23:33 #8
nu har jeg ikke kigget nærmere på hvorfor, men dine kodeforslag virker ikke hos mig.
argumenterne jeg sender er de samme som ved min egen.
Avatar billede arne_v Ekspert
17. marts 2007 - 23:36 #9
din kode og min kode gør 2 helt forskellige ting

min kode tager "A" "C" "ABC" og returnerer "B"

din kode tager "A", "B", "C" og returnrer "ABC"

det er to modsatte processer
Avatar billede kalp Novice
17. marts 2007 - 23:37 #10
nåhhh.. se jeg havde forstået spørgsmålet lidt anderledes:)
Avatar billede kalp Novice
17. marts 2007 - 23:45 #11
så må jeg jo komme med mit forslag:P

    public string BlaBlahMetoden(string TekstEt, string TekstTo, string TekstTre)
{
        TekstTre = TekstTre.Replace(TekstEt,"");
        return TekstTre.Replace(TekstTo, "");
}


virker stadig mere læsevenligt:)
Avatar billede dktekno Nybegynder
18. marts 2007 - 13:45 #12
gawi - takker, sæt svar for points.
Avatar billede kalp Novice
18. marts 2007 - 21:25 #13
får du her:)
Avatar billede md_craig Nybegynder
19. marts 2007 - 09:20 #14
ehm.... hvad skla følgende give af resultat:

("B","E","ABCDEF") ??

ACDF eller CD ?... for som jeg har forstået så CD og så er Arnes stadig den eneste korekte løsning her.
Avatar billede kalp Novice
19. marts 2007 - 09:26 #15
md_craig >> Hvis det der skal være taget i betragtning skulle spørgsmålet jo omformuleres da "B" og "E" teknisk set er char's.
Avatar billede md_craig Nybegynder
19. marts 2007 - 10:18 #16
qawi >>

Det er det da ikke... der er "" om og ike '' om... men lad mig gøre det mere forstående så...

("BC","HI","ABCDEFGHIJ")

Skal det give:

ADEFGJ eller DEFG
Avatar billede kalp Novice
19. marts 2007 - 10:31 #17
md_craig >> okay! men jeg ved skam godt hvad forskellen mellem en char og string er;o)

men du siger resultatet skal give DEFG? hvorfor giver arne's kode så

CDEFG ?? (den første)

DEF  ?? (den midterste)


og den sidste

EF



har du overhovedet testet hans kode eller kigger du bare på brugernavne og ser hvem der har mest erfaring?

her har du en kode som giver dig DEFG

public string BlaBlahMetoden(string TekstEt, string TekstTo, string TekstTre)
    {
        return TekstTre.Substring(TekstTre.IndexOf(TekstEt) + TekstEt.Length, TekstTre.LastIndexOf(TekstTo) - TekstTo.Length - 1);
    }
Avatar billede kalp Novice
19. marts 2007 - 10:35 #18
selv i dit første eksempel
"B", "E", "ABCDEF"))

der virker min nye metode.. den returnere "CD"

arnes.

kode 1.

BCD

kode 2.

C

kode 3.

giver ingenting tilbage


konklusionen må jo være at du snakker uden at teste!
Avatar billede kalp Novice
19. marts 2007 - 10:37 #19
men nok om det.. vi ved ikke hvad spørger skal bruge..
min kode vil ikke virke i alle situationer heller, men ud fra det man så fra spørgers side er den fin nok.

Jeg tror hvis man skal gøre det helt rigtigt så det virker altid så skal man lave en regexp.
Avatar billede md_craig Nybegynder
19. marts 2007 - 11:06 #20
qawi >>

Ok nu havde jeg ikke lige testet arnes kode, men lad mig sige det på den her måde så, ideen i hans var korekt... og er jo også det du bruger i din sidste blah bla...

Tror nemlig formålet var at rive en del af in streng ud baseret på du strege og ikke bare fjerne de 2 strenge...

Men om ikke andet fik då så måske løst det... det var bare bedre end at dktekno fik noget som virkede så længe at Txt1 og Txt2 var i starten og enden af strengen... mens det måske ville gå galt i det øjeblik at de også var inde mindt i strengen... ;)
Avatar billede kalp Novice
19. marts 2007 - 11:17 #21
Jeg tror stadig det skal gøres med regexp for at det virker i de fleste tilfælde:)
Avatar billede kalp Novice
19. marts 2007 - 11:33 #22
nu er jeg "elendig" til regexp.

men denne her fungere umiddelbart bedre end metoden før


    public string BlaBlahMetoden(string TekstEt, string TekstTo,string TekstTre)
    {
        Regex regexp = new Regex(TekstEt + ".*" + TekstTo);
        string newText = regexp.Match(TekstTre, 0, TekstTre.Length).Value;
        return newText.Substring(TekstEt.Length, (newText.Length - TekstTo.Length-TekstEt.Length));
    }
Avatar billede kalp Novice
19. marts 2007 - 11:37 #23
using System.Text.RegularExpressions;
Avatar billede md_craig Nybegynder
19. marts 2007 - 12:14 #24
Nu har jeg brugt regex en del og det giver da nogle muligheder, i dette tilfælde syntes jeg egentlig måske det er lidt overkill... men naturligvis smag og behag...

Enyways... hvis du bruger BackReferences burde det blive lidt nemmere:

Regex reg = new Regex(string.Format("^.*{0}(<Capture>.*){1}.*$",TekstEt,TekstTo)
return reg.Match(TekstTre).Groups["Capture"].Value;

Burde faktisk være nok.... hvis jeg husker korrekt...

Så kan man så få det der er indeholdt i paranteserne navngivet Capture mere eller mindre direkte, man skal derfor ikke til noget substring mm...

Men man skal passe på hvad man i det tilfælde gør og vide noget omkring Greedy og Non-Greedy Regex's... men jeg tror i det hele taget det er at komplecere opgaven mere end højest nødvendig...
Avatar billede kalp Novice
19. marts 2007 - 12:30 #25
det er ikke overkill med regexp... hvis du skal have det mest præcise resultat med mindst kode så er det da vejen frem:)

ellers skal du til at tage højde på ret mange ting.. f.eks hvis du får disse argumenter..

" d","e","asdtttkkkkqeee"

så ville så ville indexOf jo aldrig finde start positionen da der er mellemrum i..

og der er mange andre situationer hvor indexOf bare ikke duer til en disse.

regexp er vejen frem som jeg har sagt hele tiden.

i øvrigt testede jeg de nævnte argumenter i min regexp og det forstod den også fint:)
Avatar billede arne_v Ekspert
19. marts 2007 - 12:38 #26
med hensyn til hvad min kode returnerer så skrev jeg oppe i 17/03-2007 23:27:36
"i begge tilfælde antager jeg mellemrum som ikke skal med i resultat" - det har faktisk
en betydning

prøv og test med:

"B", "E", "A B CD E F"

+1 og -2 skal undlades hvis de mellemrum ikke skal skrælles væk
Avatar billede kalp Novice
19. marts 2007 - 12:46 #27
Jeg kan godt se at den vil fungere i det tilfælde:-).. (uden at teste den)
Avatar billede md_craig Nybegynder
19. marts 2007 - 13:06 #28
arne_v >

var det så ikke bedre at trimme mellemrun efterfølgende? :P...

qawi >

med hensyn til " d","e","asdtttkkkkqeee"...

Så vil jeg antage at det skal være resultatløst og at det er meningen, for der vil jeg mene at så har man specifikt bedt den om af finde " d" og ikke "d"... derfor vil den returnere noget der indikere at den ikke kunne finde noget.

og i sidste ende vil Regex så give langt stører problemer... da man skal til netop at kontrolere for en masse skidt og bras i tekstEt og tekstTo inputtet...

\'s, .'er, *'er, mellemrum, $, ^ ect...

Så hvis opgaven er at finde streng X som er en streng der ligger imellem streng Y og Z, så vil jeg mene at det er langt vedre bare at gøre som arne v og dig... frem for regex... for så er der ikke en masse tegn der giver bøvl, og skriver man " noget"... så må man antage at det er vigtigt at der er mellemrum inden noget...
Avatar billede kalp Novice
19. marts 2007 - 13:20 #29
md_craig >> Hvis vi vidste 100% hvordan argumenter kunne se ud i spørgers projekt så kunne også komme med en rigtig god løsning:-)

Faktum er jo at hvis data ser således ud

minfunktion("blablabla","albalbalb","blablabla dette skal være mit resultat albalbalb");


så virker de foreslag der er kommet fint.. har jo også lavet en ikke regexp løsning her

Kommentar: qawi
19/03-2007 10:31:08

Vi ved ikke om der nogensinde bliver sendt enkelte tegne som start og slut, så hvorfor diskutere vi det overhovedet:)

for mig at se kunne det spørger eftersøgte ligeså godt have været "start","slut","start hej med dig md_craig slut"

og så virker det bud han accepterede jo perfekt:o)
Avatar billede md_craig Nybegynder
19. marts 2007 - 14:31 #30
qawi >

Men der står også: "Dvs. den udskriver det, der står mellem 2 andre strings."

Og det er der jeg kommer frem til at det man vil er at tage "start" og "slut" og "en streng med start som indeholder noget tekst før og med slut og indeholder noget efter"... og så pille " som indeholder noget tekst før og med " ud...

Det er min opfattelse af spørgsmålet. for ellers vil jeg tro han havde spurgt efter at få "Fjernet" noget istedet for af "pille noget ud"...
Avatar billede dktekno Nybegynder
19. marts 2007 - 15:50 #31
Undskyld, qawi, men efter nærmere eftertanke kan jeg ikke bruge din løsning alligevel.

Din metode virker ikke, hvis jeg f.eks. har en tekst, der hedder:

"blablabla:udskriv dette her;albalbalb"

Så vil jeg f.eks. gerne have udskrevet hvad der står mellem : og ;. Hvis jeg benytter mig af dit eksempel, så får jeg følgende som resultat:

"blablablaudskriv dette heralbablalb"

Og det skal det jo ikke være. Det skal være sådan, at den tager højde for, om der er andet tekst. Jeg har en lignende kode som virker fint for mig i Delphi:


function Indlaes(FromStr, ToStr, Str: String): String;
begin
  if Pos(FromStr, Str) > 0 then
    Result := Copy(Str, Pos(FromStr, Str) + Length(FromStr), Pos(ToStr, Copy(Str, Pos(FromStr, Str) + Length(FromStr), Length(Str))) - 1)
  else
    Result := '';
end;

Se om i kan omdanne denne til C#.
Avatar billede kalp Novice
19. marts 2007 - 15:54 #32
dktekno>>

du overser det meste vi har skrevet..

jeg har lavet dette forslag som virker..

  public string BlaBlahMetoden(string TekstEt, string TekstTo, string TekstTre)
    {
        Regex regexp = new Regex(TekstEt + ".*" + TekstTo);
        string newText = regexp.Match(TekstTre, 0, TekstTre.Length).Value;
        return newText.Substring(TekstEt.Length, (newText.Length - TekstTo.Length - TekstEt.Length));
    }


og skal nok også teste det andre.
Avatar billede kalp Novice
19. marts 2007 - 15:56 #33
og : ; er jo lidt lige som start og slut...
og en info du kunne have givet for længst:o)

hvis du vil prøve den metode fra før skal du have dette med i using.
using System.Text.RegularExpressions;
Avatar billede md_craig Nybegynder
19. marts 2007 - 18:17 #34
dktekno >

Ud fra den i delphi er det noget ala:

        public static string MinFunktion(string str , string from, string to)
        {
            if ( str.Contains( from ) && str.Contains( to ) && str.IndexOf( from ) < str.IndexOf( to ) )
            {
                return str.Substring( str.IndexOf( from ) + from.Length, str.IndexOf( to ) - str.IndexOf( from ) - from.Length );
            }
            else
            {
                return "";
            }
        }

Der er lidt der er anderledes... den der er mest anderledes er:

if Pos(FromStr, Str) > 0 then VS. if ( str.Contains( from ) && str.Contains( to ) && str.IndexOf( from ) < str.IndexOf( to ) )

Fren for kun af tjecke på om FromStr eksistere, så tjeker man ok både From og To eksistere, og om To desuden ligger efter From.
Avatar billede dktekno Nybegynder
19. marts 2007 - 19:10 #35
qawi - Desværre, virker ikke.
Jeg har indsat følgende:

using System.Text.RegularExpressions;

Og derefter funktionen:

  public string BlaBlahMetoden(string TekstEt, string TekstTo, string TekstTre)
    {
        Regex regexp = new Regex(TekstEt + ".*" + TekstTo);
        string newText = regexp.Match(TekstTre, 0, TekstTre.Length).Value;
        return newText.Substring(TekstEt.Length, (newText.Length - TekstTo.Length - TekstEt.Length));
    }

Men når jeg kalder den, f.eks. ved:

string min_blahblah = BlahBlahMetoden("abc:lasse",";","abc:lasse;ejge");

så får jeg følgende fejl:

"BlahBlahMetoden denotes a namespace which is not valid in the given context"
Avatar billede dktekno Nybegynder
19. marts 2007 - 19:12 #36
md_craig - Jeg får en fejl der siger følgende:

'string' does not contain a definition for 'Contains'
Avatar billede arne_v Ekspert
19. marts 2007 - 19:21 #37
String Contain kræver .NET 2.0 eller nyere

men

str.Contains( from )

og

str.IndexOf( from ) >= 0

bør gøre det samme
Avatar billede dktekno Nybegynder
19. marts 2007 - 20:06 #38
Jeg HAR .NET 2.0

Jeg bruger Borland Developer Studio 2006, altså Borland C# Builder.
Avatar billede arne_v Ekspert
19. marts 2007 - 20:17 #39
hm - min BDS 2006 (dog kun i gratis version) kører altså med 1.1
Avatar billede kalp Novice
19. marts 2007 - 22:37 #40
dktekno >>

jo metoden virker fint.. du skal bare lige placere den korrekt for du har ikke placeret metoden et gyldigt sted ser det ud til.. måske under en forkert parantes!

en helt anden ting er at du ved dine argumenter..

BlahBlahMetoden("abc:lasse",";","abc:lasse;ejge");


jo ikke vil få noget som helst tilbage!!

du laver jo dette til din start position "abc:lasse" og dette til slut ";"
tjek teksten.. hvad er der mellem disse punkter? ingenting!!

så hvis du bare ville hive "lasse" ud skulle du have skrevet

BlahBlahMetoden(":",";","abc:lasse;ejge");


og metoden virker 100%
Avatar billede md_craig Nybegynder
20. marts 2007 - 09:32 #41
dktekno >>

Har nu ellers testet og fundet frem til det virkede :D...
Men som arne siger, vær helt sikker på at det du compiler til er 2.0, det kan godt være du har hentet .NET 2.0 on installeret det mm. men hvis du i din Borland compiler til en .NET 1.1 så gør det ikke den store forskel...

Alternativt kan du som arne siger bare udskifte den med str.IndexOf( from ) >= 0, giver samme resultat... og så minder det jo også endnu mere om det delphi kode du har :P...

Det jeg postede er en modificering af det arne gav dig langt tidligere...
Avatar billede md_craig Nybegynder
20. marts 2007 - 09:46 #42
using System;
using System.Text;

namespace Oema.Presentation
{
  public class MinClass
  {
//    public static string MinFunktion20(string str, string from, string to)
//    {
//      if ( str.Contains( from ) && str.Contains( to ) && str.IndexOf( from ) < str.IndexOf( to ) )
//      {
//        return str.Substring( str.IndexOf( from ) + from.Length, str.IndexOf( to ) - str.IndexOf( from ) - from.Length );
//      }
//      else
//      {
//        return "";
//      }
//    }

    public static string MinFunktion11(string str, string from, string to)
    {
      if ( ( str.IndexOf( from ) >= 0 ) && ( str.IndexOf( to ) >= 0 ) && str.IndexOf( from ) < str.IndexOf( to ) )
      {
        return str.Substring( str.IndexOf( from ) + from.Length, str.IndexOf( to ) - str.IndexOf( from ) - from.Length );
      }
      else
      {
        return "";
      }
    }

    public static Main()
    {
      string minStr = "min streng som jeg vil finde noget i";

      //Burde begge give resultatet: " som jeg vil "
      //Console.WriteLine( "{0}{1}{0}", "\"", MinFunktion20( minStr, "streng", "finde" ) )
      Console.WriteLine( "{0}{1}{0}", "\"", MinFunktion11( minStr, "streng", "finde" ) )

      string dinStr = "abc:lasse;ejge";

      //Burde begge give resultatet: "lasse"
      //Console.WriteLine( "{0}{1}{0}", "\"", MinFunktion20( minStr, ":", ";" ) )
      Console.WriteLine( "{0}{1}{0}", "\"", MinFunktion11( minStr, ":", ";" ) )
    }
  }
}

Den kan du evt. kopiere ind og kige på, og så udkommentere metoden og kaldene til den der heder MinFunktion20 til at starte med... den anden burde nemlig virke i .NET 1.1
Avatar billede dktekno Nybegynder
20. marts 2007 - 22:14 #43
Kalp - takker.
Avatar billede kalp Novice
20. marts 2007 - 23:19 #44
ingen årsag
Avatar billede md_craig Nybegynder
21. marts 2007 - 10:35 #45
dktekno >

Hvis du bruger Regex skal du som sagt passe på, nu ved jeg ikke hvor meget du styrer inputtet selv, men du kan få nogle grimme situationer ud af det.

      Console.WriteLine( BlaBlahMetoden( "|", ".", "abc|lasse.ejge" ) );
      Console.WriteLine( BlaBlahMetoden( "[", "]", "abc[lasse]ejge" ) );
      Console.WriteLine( BlaBlahMetoden( ":", ";", "abc:lasse;ejge" ) );

Der giver de 2 første dig nogle grimme situationer.... følgende tegn har du udelukket som seperator tegn med det du har nu: [\^$.|?*+()

Ellers skal du først Escape dem... hvis du fx vil matche \ skal du bruge \\ (og i .NET kode "\\\\" resten er bare \[ \^ \$ \. ect. du kan læse mere her:

http://www.regular-expressions.info/reference.html

En anden ting er, hvis man benytter Regex, kan man sQ lige så godt gå "All the way"..

  public string BlaBlahMetoden(string TekstEt, string TekstTo, string TekstTre)
    {
        Regex regexp = new Regex(TekstEt + ".*" + TekstTo);
        string newText = regexp.Match(TekstTre, 0, TekstTre.Length).Value;
        return newText.Substring(TekstEt.Length, (newText.Length - TekstTo.Length - TekstEt.Length));
    }

De sidste 2 linier er lidt noget bras når vi alligevel er i gang med regex når tingene kan gøres meget nemmere.

    public static string BlaBlahMetoden(string TekstEt, string TekstTo, string TekstTre)
    {
      Regex reg = new Regex(string.Format("{0}(?'C'.*){1}",TekstEt,TekstTo));
      return reg.Match( TekstTre ).Groups["C"].Value;
    }

Var også det jeg viste med Regex tidligere, men der var lige lidt syntax messige ting der manglede... ? inde i de paranteser der indeholder det vi gerne vil fange er rimelig essentiel ellers får man ikke noget Capture ud af det, og derfor det ikke har virket :P... om man så bruger '' eller <> til at navngive captured er ligemeget...
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