Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6986385
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T18:48:07+00:00 2026-05-27T18:48:07+00:00

(sorry in advance for the long question – the problem is actually simple –

  • 0

(sorry in advance for the long question – the problem is actually simple – but to explain it is maybe not so simple )

My noobie skills in PHP are challenged by this :

Input of 2 TXT files with a structure like this :

$rowidentifier //number,letter,string etc..
$some semi-fixed-string $somedelimiter $semi-fixed-string
$content //with unknown length or strings or lines number.

reading the above , my meaning in “semi-fixed-string, means that it is a string with a KNOWN structure, but UNKNOWN content..

to give a practical example, let´s take an SRT file (i just use it as a guinea pig as the structure is very similar to what I need ):

1
00:00:12,759 --> 00:00:17,458
"some content here "
that continues here

2
00:00:18,298 --> 00:00:20,926
here we go again...

3
00:00:21,368 --> 00:00:24,565
...and this can go forever...

4
.
.
.

what I want to do , is to take the the $content part from one file, and put it IN THE RIGHT PLACE at the second file .

going back to the example SRT , having :

//file1 

    1
    00:00:12,759 --> 00:00:17,458
    "this is the italian content "
    which continues in italian here

    2
    00:00:18,298 --> 00:00:20,926
    here we go talking italian again ...

and

//file2 

    1
    00:00:12,756 --> 00:00:17,433
    "this is the spanish, chinese, or any content "
    which continues in spanish, or chinese here

    2
    00:00:16,293 --> 00:00:20,96
    here we go talking spanish, chinese or german again ...

will result in

//file3 

        1
        00:00:12,756 --> 00:00:17,433
        "this is the italian content "
        which continues in italian here
        "this is the spanish, chinese, or any content "
        which continues in spanish, or chinese here

        2
        00:00:16,293 --> 00:00:20,96
        here we go talking italian again ...
        here we go talking spanish, chinese or german again ...

or more php like :

$rowidentifier //unchanged
$some semi-fixed-string $somedelimiter $semi-fixed-string //unchanged, except maybe an option to choose if to keep file1 or file2 ...
$content //from file 1
$content //from file 2

so, after all this introduction – this is what I have (which amounts to nothing actually..)

$first_file = file('file1.txt'); // no need to comment right ?
$second_file = file('file2.txt'); // see above comment
$result_array = array(); /construct array
foreach($first_file as $key=>$value) //loop array and.... 
$result_array[]= trim($value).'/r'.trim($second_file[$key]); //..here is my problem ...

// $Value is $content - but LINE BY LINE , and in our case, it could be 2-3- or even 4 lines
// should i go by delimiters /n/r ??  (not a good idea - how can i know they are there ?? )
// or should i go for regex to lookup for string patterns ? that is insane , no ?

$fp = fopen('merge.txt', 'w+'); fwrite($fp, join("\r\n", $result_array); fclose($fp);

this will do line by line – which is not what i need. I need conditions..
also – I am sure this is not a smart code, or that there are many better ways to go at it – so any help would be appreciated …

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T18:48:08+00:00Added an answer on May 27, 2026 at 6:48 pm

    What you actually want to do is to iterate over both files in parallel and then combine the part belonging to each other.

    But you can not use the line numbers, because those might differ. So you need to use the number of the entry (block). So you need to give it a “number” or more precise, to get out one entry after the other from a file.

    So you need an iterator for the data in question that is able to turn some lines into a block.

    So instead of:

    foreach($first_file as $number => $line)
    

    it is

    foreach($first_file_blocks as $number => $block)
    

    This can be done by writing your own iterator that takes a file’s line as input and will then convert lines into blocks on the fly. For that you need to parse the data, this is a small example of a state based parser that can convert lines into blocks:

    $state = 0;
    $blocks = array();
    foreach($lines as $line)
    {
        switch($state)
        {
            case 0:
                unset($block);
                $block = array();
                $blocks[] = &$block;
                $block['number'] = $line;
                $state = 1;
                break;
            case 1:
                $block['range'] = $line;
                $state = 2;
                break;
            case 2:
                $block['text'] = '';
                $state = 3;
                # fall-through intended
            case 3:
                if ($line === '') {
                    $state = 0;
                    break;
                }
                $block['text'] .= ($block['text'] ? "\n" : '') . $line;
                break;
            default:
                throw new Exception(sprintf('Unhandled %d.', $state));
        }
    }
    unset($block);
    

    It just runs along the lines and changes it’s state. Based on that state, each line is processed as part of it’s block. If a new block begins, it will be created. It works for the SRT file you’ve outline in your question, demo.

    To make the use of it more flexible, turn it into an iterator which takes $lines in it’s constructor and offers the blocks while iterating. This needs some little adoption how the parser gets the lines to work on but it works generally the same.

    class SRTBlocks implements Iterator
    {
        private $lines;
        private $current;
        private $key;
        public function __construct($lines)
        {
            if (is_array($lines))
            {
                $lines = new ArrayIterator($lines);
            }
            $this->lines = $lines;
        }
        public function rewind()
        {
            $this->lines->rewind();
            $this->current = NULL;
            $this->key = 0;
        }
        public function valid()
        {
            return $this->lines->valid();
        }
        public function current()
        {
            if (NULL !== $this->current)
            {
                return $this->current;
            }
            $state = 0;
            $block = NULL;
            while ($this->lines->valid() && $line = $this->lines->current())
            {
                switch($state)
                {
                    case 0:
                        $block = array();
                        $block['number'] = $line;
                        $state = 1;
                        break;
                    case 1:
                        $block['range'] = $line;
                        $state = 2;
                        break;
                    case 2:
                        $block['text'] = '';
                        $state = 3;
                        # fall-through intended
                    case 3:
                        if ($line === '') {
                            $state = 0;
                            break 2;
                        }
                        $block['text'] .= ($block['text'] ? "\n" : '') . $line;
                        break;
                    default:
                        throw new Exception(sprintf('Unhandled %d.', $state));
                }
                $this->lines->next();
            }
            if (NULL === $block)
            {
                throw new Exception('Parser invalid (empty).');
            }
            $this->current = $block;
            $this->key++;
            return $block;
        }
        public function key()
        {
            return $this->key;
        }
        public function next()
        {
            $this->lines->next();
            $this->current = NULL;
        }
    }
    

    The basic usage is the following, the output can be seen in the Demo:

    $blocks = new SRTBlocks($lines); 
    foreach($blocks as $index => $block)
    {
        printf("Block #%d:\n", $index);
        print_r($block);
    }
    

    So now it’s possible to iterate over all blocks in a SRT file. The only thing left now is to iterate over both SRT files in parallel. Since PHP 5.3 the SPL comes with the MultipleIterator that does this. It’s now pretty straight forward, for the example I use the same lines twice:

    $multi = new MultipleIterator();
    $multi->attachIterator(new SRTBlocks($lines));
    $multi->attachIterator(new SRTBlocks($lines));
    
    foreach($multi as $blockPair)
    {
        list($block1, $block2) = $blockPair;
        echo $block1['number'], "\n", $block1['range'], "\n", 
            $block1['text'], "\n", $block2['text'], "\n\n";
    }
    

    To store the string (instead of outputting) into a file is rather trivial, so I leave this out of the answer.

    So what to remark? First, sequential data like lines in a file can be easily parsed in a loop and some state. That works not only for lines in a file but also across strings.

    Second, why did I suggest an iterator here? First it’s easy to use. It was only a small step from handling one file to two files in parallel. Next to that, the iterator can actually operate on another iterator as well. For example with the SPLFileObject class. It provides an iterator over all lines in a file. If you have large files, you can just use the SPLFileObject (instead an array) and you won’t need to load both files into arrays first, after a small addition to SRTBlocks that removes trailing EOL characters from the end of each line:

    $line = rtrim($line, "\n\r");
    

    It just works:

    $multi = new MultipleIterator();
    $multi->attachIterator(new SRTBlocks(new SplFileObject($file1)));
    $multi->attachIterator(new SRTBlocks(new SplFileObject($file2)));
    
    foreach($multi as $blockPair)
    {
        list($block1, $block2) = $blockPair;
        echo $block1['number'], "\n", $block1['range'], "\n", 
            $block1['text'], "\n", $block2['text'], "\n\n";
    }
    

    That done you can process even really large files with (nearly) the same code. Flexible, isn’t it? The full demonstration.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Sorry in advance as this question is similar (but not the same!) to others.
Sorry in advance for the long question. What I'm really interested in is a
In advance: sorry for the noob question but I'm learning Cocoa & Objective-C and
Sorry if this is too simple, but thanks in advance for helping. This is
Sorry for this not being a real question, but Sometime back i remember seeing
Sorry in advance for the long question, it's long because I've been digging at
Sorry for the long explanation. Thanks in advance to all who are taking their
Sorry in advance, I'm struggling a bit with how to explain this... :) Essentially,
Sorry for the second newbie question, I'm a developer not a sysadmin so this
Sorry for the long title, didn't want people just reading the title and not

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.