Split

Dag B.

Aktives Mitglied
Hallo,

folgendes Problem:
Ich nutze in 2 verschiedenen Programmen split, verstehe aber nicht wo im Quelltext der Unterschied ist, dass ich ein unterschiedliches Ergebnis kriege...

Eingelesen wird ein FASTA-File der Art:

>seq

AGTGGG

>andereseq

GTAGTGA

Java:
/*Spliting the single entrys*/
        final String NAMESTART_SYMBOL = ">"; /*The greater as symbol is in front of each 
                                  * name so substring can find the name using this*/
        final String WHITESPACE = " "; //The first whitespace in the file is at the end of the name
        String []entrys = file.split(NAMESTART_SYMBOL); //The arrayfield which will contain the entrys which where splited at the >
        
        /*Gets the names of the sequences and puts them in the array seq_names*/
        int number_of_entrys = entrys.length; /*Each field of the array contains 
         * one entry so the number of fields == number of entrys*/
        //TODO: Container???
        int wildtype_seq_position = use_of_mut_sides ? 0 : 1;
        if(number_of_entrys < wildtype_seq_position+2) //Less than 2/3 (if no/there is mut_side_seq) sequences/entries are not legal as you need at least a wildtype and another for comparison
        {
                throw new IllegalArgumentException("Found too less sequences");
        }
        
        number_of_entrys--; /* split() fabricates a entry which only contains a newline. 
         * This one isn't used but is count so the arraybounds will set wrong without the -1*/
        seq_names = new String[number_of_entrys]; //the field (seq_names) which gets the names 
        for(int i=1; i<=number_of_entrys;i++) //The entry[0] dosn't exist so the counter starts at 1
        {
             int start = entrys[i].indexOf(NAMESTART_SYMBOL); //Get the start of the name which contains ">"
             //TODO: ERROR: No namestart_symbol found
             int end = entrys[i].indexOf(WHITESPACE); //Get the end of the name which is at the first whitespace
             //TODO: ERROR: No end of name/whitespace found
             if(end <= -1) //If there was no whitespace for the end of entry found or an unlegal number comes up
             {
                    throw new IllegalArgumentException("Found no entry-end");
             }
             seq_names[i-1] = entrys[i].substring(start+1, end); //Saves the name of the sequence
        }
Hier sehen die Einträge so aus:
>seq

ATGGTT

Java:
        final String NAMESTART_SYMBOL = ">";
       String[] entries = file.split(NAMESTART_SYMBOL); //The arrayfield which will contain the entrys which where splited at the >
       System.out.println(entries[1] + " " + entries[2]);
       for(int i=1; i < entries.length; i++) {
            int start = entries[i].indexOf(NAMESTART_SYMBOL); //Get the start of the name which contains ">"
            int end = entries[i].indexOf(" "); //Get the end of the name which is at the first whitespace
            System.out.println(start + " " + end);
           // System.out.println(entries[i].substring(start, end));
       }
    }
Hier sehen die Einträge so aus:
seq

ATGGG

Es fehlt also das führende ">" wodurch mein indexOf nicht mehr funktioniert. Ich könnte es einfach auf 0 setzen weil es ja das erste Zeichen ist, aber ich würde eben gerne verstehen warum da was unterschiedliches bei rauskommt???
Ich habe auch testweise genau die gleichen Files eingelesen, es liegt also nicht an der Eingabe.

Die Einleseroutine habe ich aus dem ersten Programm fürs zweite kopiert, auch hier sind also keine Unterschiede...

Java:
        /* Reading from the file*/
        String file = null; //Will get the file
        StringBuffer input = new StringBuffer();
	String line = null; //Will get a single line of the file
        
        try {
            BufferedReader buffreader = new BufferedReader(new FileReader(file_name));
            while ((line = buffreader.readLine()) != null) //read
            file = (input.append(System.getProperty("line.separator")).append(line)).toString(); //and put it in the input

        } catch (FileNotFoundException ex) {
            System.err.println(ex);
            ex.printStackTrace();
            System.exit(-1);
        } catch (IOException ex) {
            System.err.println(ex);
            ex.printStackTrace();
            System.exit(-1);
        }
 
String (Java Platform SE 6)

die ausgaben sind bei mir gleich. option 1 wirft zwar bei mir eine exception aber ">" geht beim split definitiv verloren...

mal abgesehn davon, dass ich deine Vorgehensweiße etwas wüst und umständlich finde.

grüße
nrg

edit: wenn du das Trennzeichen mit ausgeben willst, fällt mir eigentlich nur der StringTokenizer ein. (StreamTokenizer wär eine sehr schöne Variante aber da hab ich jetzt die Möglichkeit das Trennzeichen zurückzugeben nicht gefunden.)
Java:
StringTokenizer(String str, String delim, boolean returnDelims) 
          Constructs a string tokenizer for the specified string.

ich weiß halt auch nicht wie es nach dem Tokenizen aussehen soll bzw was du vor hast.

edit2: ich seh auch erst jetzt, dass du die Stringzeichen vertauscht. Hab mich jetzt erstmal nur auf den split bzw auf das ">" geachtet. sag doch einfach mal was du vor hast 😉. vllt steh ich grad auch nur aufm schlauch :rtfm:
 
Zuletzt bearbeitet:
whau haette nicht gedacht hier mal FASTA dateien zu sehen.

was du eigentlich lesen willst ist mir nciht klar ? die Bezeichneier ? die Sequenzen ? TeilSequenzen

und eine FASTA datei ohne [c]>[/c] ist nicht gueltig - also irrelevant

Code:
LEISE
LIED
KEIN
was davon ist nun ein Protein und was der Bezeichner ?
 
String (Java Platform SE 6)

die ausgaben sind bei mir gleich. option 1 wirft zwar bei mir eine exception aber ">" geht beim split definitiv verloren...
Das ist aber komisch, da er beim ersten Quelltext definitiv bei
Java:
int start = entrys[i].indexOf(NAMESTART_SYMBOL); //Get the start of the name which contains ">"
etwas findet...


edit2: ich seh auch erst jetzt, dass du die Stringzeichen vertauscht. Hab mich jetzt erstmal nur auf den split bzw auf das ">" geachtet. sag doch einfach mal was du vor hast 😉. vllt steh ich grad auch nur aufm schlauch :rtfm:
Wo vertausche ich denn Stringzeichen?


Vorhaben tue ich folgendes:
Ich möchte ein FASTA-File mit folgender (festgelegter) Formatierung einlesen:
>wildtype

AGTCGTAGCGTAGCAGTAC

>hpf

AGTGGTAGGGCAGCAGTAC
mit beliebig vielen weiteren Einträgen.

Um damit arbeiten zu können, teile ich die Datei erstmal in die einzelnen Einträge auf per split. Da bei jedem > ein neuer Eintrag/eine neue Sequence beginnt, ist es natürlich am praktischtes dort zu teilen.

Anschließend möchte ich erstmal den Namen auslesen. Dieser steht immer hinter dem >. Also suche ich erstmal den Index davon.
Wie bereits erwähnt ist dies allerdings im Nachhinein hinfällig, da das > ja immer das erste Zeichen jedes Eintrages ist.
Der Name endet mit einem Whitespace, daher kann ich so das Ende des Namens suchen.

In erstem Programm wird der Name dann zur Weiterverwendung abgelegt, im zweiten passiert noch nichts weiter, da dort für den startindex immer -1 zurückgegeben wird (weil das > ja nicht mehr im Eintrag vorhanden ist).


Was ich nicht verstehe ist folgendes:

Bei ersterem Programm wird "start" korrekt mit 0 angegeben.
Beim zweiten Programm wird immer -1 ausgegeben und demnach natürlich beim aktuell herauskommentierten substring ein Fehler produziert.

Denn der Splitbefehl ist ja genau derselbe und auch die gleiche Datei habe ich einmal eingelesen um auszuschließen, dass es an der Eingabe liegt. :/
 
Dag B. hat gesagt.:
>wildtype

AGTCGTAGCGTAGCAGTAC

>hpf

AGTGGTAGGGCAGCAGTAC
  1. Datei aufteilen mit String#split(String), gibt dir ein Array mit den Paaren Name / Sequenz.
  2. Mit einem StringTokenizer bei jedem einzelnen Paar Namen und Sequenz holen (erst prüfen, dann holen).

Übrigens:
Dag B. hat gesagt.:
[JAVA=11]
catch (FileNotFoundException ex) {
System.err.println(ex);
ex.printStackTrace();
System.exit(-1);
} catch (IOException ex) {
System.err.println(ex);
ex.printStackTrace();
System.exit(-1);
}
[/code]
Code:
FileNotFoundException
erbt von
Code:
IOException
, wenn du also bei beiden das gleiche machen willst, reicht es, die
Code:
IOException
zu fangen.

Und:
Dag B. hat gesagt.:
[JAVA=7]
BufferedReader buffreader = new BufferedReader(new FileReader(file_name));
while ((line = buffreader.readLine()) != null) //read
file = (input.append(System.getProperty("line.separator")).append(line)).toString(); //and put it in the input
[/code]
😱

:arrow:
Java:
		StringBuilder sb = new StringBuilder();
		Scanner sc = new Scanner(new File("C:/test.txt"));
		
		while (sc.hasNextLine())
		{
			sb.append(sc.nextLine());
			sb.append(System.getProperty("line.separator"));
		}
		
		String fileContent = sb.toString();
 
was spricht dagegen direkt beim Einlesen in eine Liste zu schreiben? (bin mir da weng unsicher, weil mir FASTA bis dato soviel sagt, wie ich auf Wikipedia dazu finden konnte :rtfm🙂

Java:
		boolean headerRead = false;
		String line;
		String[] sequence = new String[3];
		LinkedList<String[]> file = new LinkedList<String[]>();
		  try{
	          BufferedReader buffreader = new BufferedReader(new FileReader("test.txt"));
	          while ((line = buffreader.readLine()) != null){
	        	  if (!line.equals("")){
		        	  if (headerRead && line.charAt(0) == '>'){
		        		  file.add(sequence);
		        		  sequence = new String[3];
		        		  headerRead = false;
		        	  }
		        	  switch (line.charAt(0)){
		        	  case '>':
		        		  sequence[0] = line.substring(1);
		        		  headerRead = true;
		        		  break;
		        	  case ';':
		        		  if (sequence[1] == null)
		        			  	sequence[1] = line.substring(1);
		        		  else
		        	  			sequence[1] = sequence[1] + "-" + line.substring(1);
		        		  break;
		        	  default:
		        		  if (sequence[2] == null)
	  			  				sequence[2] = line;
		        		  else
		        			  sequence[2] = sequence[2] + line;
		        		  break;
		        	  }
	        	  }
	          }
	          file.add(sequence);

In jedem Element der Liste haste dann eine komplette Sequenz, die unterteilt ist in:
sequence[0] = ">...." ohne ">"
sequence[1] = die Kommentare ohne ";" und mit "-" verbunden
und sequence[2] = der Code (mehrere Zeilen sind einfach ohne Trennung miteinander in einem String zusammengefasst)

Kommentare kann man ja rausnehmen, falls nicht benötigt. Leerzeilen werden ignoriert.

Hoffe ich konnte dir vllt auch als Leihe im Thema Bioinformatik etwas weiterhelfen 😳

Wie auch immer. schönes wochenende 😉
nrg

edit:
meine "text.txt":
Code:
>Sequenz 1
;Kommentarzeile A
MTEITAAMVKELRESTGAGMMDCKNALSETNGDFDKAVQLLREKGLGKAAKKADRLAAEG
LVSVKVSDDFTIAAMRPSYLSYEDLDMTFVENEYKALVAELEKENEERRRLKDPNKPEHK
IPQFASRKQLSDAILKEAEEKIKEELKAQGKPEKIWDNIIPGKMNSFIADNSQLDSKLTL
MGQFYVMDDKKTVEQVIAEKEKEFGGKIKIVEFICFEVGEGEVAAQL

>Sequenz 2
;Kommentarzeile B
;Kommentarzeile C
SATVSEINSETDFVAKNDQFIALTKDTTAHIQSNSLQSVEELHSSTINGVKFEEYLKSQI
ATIGENLVVRRFATLKAGANGVVNGYIHTNGRVGVVIAAACDSAEVASKSRDLLRQICMH
>Sequenz 3
;Kommentarzeile D
ATIGENLVVRRFATLKAGANGVVNGYIHTNGRVGVVIAAACDSAEVASKSRDLLRQICMH
LVSVKVSDDFTIAAMRPSYLSYEDLDMTFVENEYKALVAELEKENEERRRLKDPNKPEHK
IPQFASRKQLSDAILKEAEEKIKEELKAQGKPEKIWDNIIPGKMNSFIADNSQLDSKLTL
 
Zuletzt bearbeitet:
Ok, also einigen wir uns darauf dass niemand weiß warum das 1. Split funktioniert und das 2. Split nicht. :autsch:

Schade.
 
kann es sein, dass du unter all deinem unverständlichen Code folgendes simples Problem meinst?:
Java:
public class Test
{
    public static void main(String[] args)
    {
        String st = "aaaxbbb";
        System.out.println(Arrays.toString(st.split("x")));
    }
}
-> Ausgabe: [aaa, bbb], das x ist verschwunden


da liegt keine Magie dahinter, das ist nunmal so,
die split-Methode führt zu Pattern.split() und darin steht ungefähr

Java:
  while(m.find()) {
           
                String match = input.subSequence(index, m.start()).toString();
                matchList.add(match);
                index = m.end();
also es wird immer alles bis Anfang eines Fundes aufgenommen, startend von 0 oder dem Ende des letzen Fundes,
ergo wird das, was dem Pattern entspricht (hier "x") ausgelassen,
wenn man das nicht will muss man wohl eine kleine neue split-Methode schreiben,
ich sehe keine Konfiguration um das zu ändern
 
das hab ich ihn aber schon im 2ten Post gesagt (nur nicht so ausführlich).

weiß echt nicht, was Dag B. noch genau wissen will..
 
-> Ausgabe: [aaa, bbb], das x ist verschwunden


da liegt keine Magie dahinter, das ist nunmal so,

Die Magie ist, dass beim ersten Javaquelltext das x stehen bleibt, es beim zweiten aber wie offensichtlich normal verschwindet. Aber warum bleibt es einmal da und verschwindet einmal bei genau dem gleichen Quelltext? :shock:
 
nun gut, aber wie nrg damals auch schon schrieb ist das für niemanden sonst nachvollziehbar,
wenn ich deinen Code kopiere und ihn auf

String file = ">test >xy ";
loslasse, dann gibts kein > in der Ausgabe,
du könntest jetzt noch eine Testdatei hochladen, aber ich glaube dazu nicht wirklich an Änderung
start wird immer -1 sein, -1 heißt nicht gefunden,

aber hier vielleicht die Lösung:
im ersten Code steht
> entrys.substring(start+1, ..); aus der -1 wird 0,

im zweiten Code steht
// System.out.println(entries.substring(start, end));
da wird die -1 zur Exception führen
 
nun gut, aber wie nrg damals auch schon schrieb ist das für niemanden sonst nachvollziehbar,
wenn ich deinen Code kopiere und ihn auf

String file = ">test >xy ";
loslasse, dann gibts kein > in der Ausgabe,
du könntest jetzt noch eine Testdatei hochladen, aber ich glaube dazu nicht wirklich an Änderung
start wird immer -1 sein, -1 heißt nicht gefunden,
Naja, genau das habe ich doch vorher gesagt. ???:L
Es weiß keiner warums bei mir geht und sonst nicht, von daher...
aber hier vielleicht die Lösung:
im ersten Code steht
> entrys.substring(start+1, ..); aus der -1 wird 0,

im zweiten Code steht
// System.out.println(entries.substring(start, end));
da wird die -1 zur Exception führen

Nein, das stimmt nicht.

Das +1 muss dort sein WEIL das > nicht abgeschnitten wird.

Was bekomme wenn ich die substring-Suche mache ist:
>SeqName

Was ich möchte is aber nur das SeqName, ohne das >. Deswegen muss ich den Index noch um einen verschieben, um eben das > "wieder los zu werden".
Somit wird beim ersten Code nicht auf -1 eine 0, sondern aus der 0 eine +1.
Sehe ich ja an den Debug-Ausgaben die ich dazwischenquetschen kann. ^^

Ich hab inzwischen einfach das File des ersten Codes in das Programm zu dem der 2. gehören sollte kopiert und es geht genauso wie beim ersten Mal. Löst natürlich nicht die Frage, darum gings mir ja nur.

Aber bevors nochmal jemand schreibt:
Ist schon ok wenns bei euch nich reproduzierbar ist, ich habe keinerlei Probleme mit der ganzen Sache, es hatte mich nur eben gewundert. Wenn ihr nix dazu sagen könnt ist das vollkommen ok und verständlich.
 

Neue Themen


Zurück
Oben