3 lines in clipboard, paste it at the end of current, next and the second next lines
-
Hi
Working on an .srt file I’ve got thousand times where 3 lines from the next saying should be moved to the previous. It looks like
before editing256 00:11:36,000 --> 00:11:38,000 Nein, ich habe es wirklich ehrlich gemeint. Non, j'étais vraiment sincère. No, I really meant it honestly. 257 00:11:40,000 --> 00:11:41,000 Ach ja? Ah oui ? Is that so?
after editing
00:11:36,000 --> 00:11:41,000 Nein, ich habe es wirklich ehrlich gemeint. Ach ja? Non, j'étais vraiment sincère. Ah oui ? No, I really meant it honestly. Is that so?
Sometimes I’ve got to remove a saying in the middle, so it’s not like always the next saying should be merged with the previous. In such a case an example would contain saying #256, #257 and #258 and the moving around would have to be made between #256 and #258. Therefore, the best thing would be to copy a saying and then have a special paste command that only inserts the first line from the clipboard to the end of the current line. Inserts the second line from the clipboard to the end of the line below. And the third one to the end of the 3rd line of a saying.
Is there a way to solve this? -
@Nick-Kat said in 3 lines in clipboard, paste it at the end of current, next and the second next lines:
have a special paste command that only inserts the first line
No such thing is available in Notepad++.
However, if you showed us an example of before/after with the 256/257/258 version, someone might be able to help you come up with a reasonable approximation of what you want. But as it is, your explanation isn’t sufficient for me to understand where your problem lies.
And if there is no programmatic/pattern-matching way of telling the difference between a 2-group merge and 3-group merge, you will probably be out of luck… but again, because you don’t clearly show examples of all the “weird” cases, I cannot be sure… maybe it’s not as complicated as your explanation makes it seem.
-
You can get close to what you want using a rectangular selection.
First, to make this as efficient as possible, from the Settings menu select Preferences, then Editing and check the box labeled Enable virtual space — this will let you drag the selection you’ll be making exactly where you want it.
Put the cursor at the beginning of the first line of the second group.
Hold down the Alt key, then press the left mouse button and drag to make a rectangle that encloses all the text you want to move. (Don’t worry if it encloses extra space on the right.) Release the mouse button.
Make sure the mouse cursor is over the selection (an arrow, not a text cursor), press the left mouse button and drag up to the first line into which you want to move. Be sure the mouse is at least one space to the right of the longest line into which you are pasting and then release the mouse button.
That will move the rectangular selection so that the top left corner of the selection is in the place where you released the mouse button.
You will have extra spaces following the shorter lines of the first group. If — as is likely in a subtitle file — there are no intentional double spaces, you can clear all the extra spaces at once when you are finished with a regular expression search (find “ +” and replace with “ ”).
Of course, you’ll still need to delete the empty lines and the subtitle number and times before them. However, from your description of the task, it sounds like you’ll need to examine each pair of titles individually anyway; the rectangular selection drag will speed up the multi-line move.
-
@Coises said in 3 lines in clipboard, paste it at the end of current, next and the second next lines:
You can get close to what you want using a rectangular selection.
Did you notice the OP said, “I’ve got thousand times where 3 lines from the next saying should be moved to the previous”. Do you really want to do 1000 individual rectangular selections? Does it really make sense to suggest that to the OP?
-
@Coises Fantastic! Works like a charm!! Thanks a lot!!!
-
@Nick-Kat Here’s another way using a regular-expression search/replace:
Search:
^(?'A_number'[0-9]+)(?'newline'\R)(?'A_start'[0-9][0-9]:[0-9][0-9]:[0-9][0-9],000) --> (?'A_end'[0-9][0-9]:[0-9][0-9]:[0-9][0-9],000)\R(?'A_text_1'.+)\R(?'A_text_2'.+)\R(?'A_text_3'.+)\R\R+(?'B_number'[0-9]+)\R(?'B_start'[0-9][0-9]:[0-9][0-9]:[0-9][0-9],000) --> (?'B_end'[0-9][0-9]:[0-9][0-9]:[0-9][0-9],000)\R(?'B_text_1'.+)\R(?'B_text_2'.+)\R(?'B_text_3'.+)$
Replace:
$+{A_number}$+{newline}$+{A_start} --> $+{B_end}$+{newline}$+{A_text_1} $+{B_text_1}$+{newline}$+{A_text_2} $+{B_text_2}$+{newline}$+{A_text_3} $+{B_text_3}
What is happening here? :-)
- I decided to call the two groups of lines A and B.
- For each group I grab the number on the first line, the start time, end time, and the three lines of text.
- Also, when picking up the “A” group I picked up one more storage spot called “newline” that contains whatever character(s) your file is using between lines.
- I then merged the groups in the replacement part.
- To make things easier to follow, I named the fields, rather than using the numbered \1, \2, \3 often seen in regular expression examples.
You mentioned needing to this thousands of times. One thought I had is rather than doing the search/replace one by one as needed than you add a marker to your file at those spots where you need to merge the entries. For example, you could add a line in front with
~merge this~
so that your block reads~merge this~ 256 00:11:36,000 --> 00:11:38,000 ...
As you are reviewing the file you add a
~merge this~
in front of each pair of blocks that needs merging. Then fix up the search part to start with^~merge this~
and use search/replace-all once you are ready to do the merge. If your data file supports comments such as a leading#
then use# ~merge this~
as the prefix meaning you can leave the tags in your file. If comments are supported then the replace can have# ~merged~$+{newline}
or whatever you want at the front of the newly merged blocks. -
Hello @nick-Kat, @Peterjones, @coises, @mkupper and All,
@mkupper, an other way to easily identify the search regex is to use the free-spacing mode
(?x)
, as below :- SEARCH :
(?x-is) # FREE-SPACING mode, SENSITIVE to case and DOT not matching EOL (?s: ^ :M: .+? ) \K # NON-NEEDED stuff AFTER the string :M: and BEFORE the SENTENCES ^( [[:alpha:]].+ ) \R+ # Group 1, without EOL ( Line 1 ) ( .+ ) \R+ # Group 2, without EOL ( Line 2 ) ( .+ ) # Group 3, without EOL ( Line 3 ) (?s: .+? ) # NON-NEEDED stuff BEFORE the SECOND group of SENTENCES ^ ( [[:alpha:]].+ \R ) \R* # Group 4, with EOL ( Line 4 ) ( .+ \R ) \R* # Group 5, with EOL ( Line 5 ) ( .+ ) # Group 6, without EOL ( Line 6 )
- REPLACE :
\1 \4\2 \5\3 \6
( with a space character between\1
and\4
,\2
and\5
,\3
and6
)
I suppose that EACH range, to be processed by the regex S/R, is identified by a line beginning with the
:M:
string
Thus, this example of INPUT with some EMPTY lines, anywhere :
:M: 256 00:11:36,000 --> 00:11:38,000 Nein, ich habe es wirklich ehrlich gemeint. Non, j'étais vraiment sincère. No, I really meant it honestly. 257 00:11:40,000 --> 00:11:41,000 Ach ja? Ah oui ? Is that so? :M: 258 00:11:36,000 --> 00:11:38,000 Non, j'étais vraiment sincère. Nein, ich habe es wirklich ehrlich gemeint. No, I really meant it honestly. 259 00:11:40,000 --> 00:11:41,000 Ah oui ? Ach ja? Is that so?
Would end up to this expected OUTPUT :
:M: 256 00:11:36,000 --> 00:11:38,000 Nein, ich habe es wirklich ehrlich gemeint. Ach ja? Non, j'étais vraiment sincère. Ah oui ? No, I really meant it honestly. Is that so? :M: 258 00:11:36,000 --> 00:11:38,000 Non, j'étais vraiment sincère. Ah oui ? Nein, ich habe es wirklich ehrlich gemeint. Ach ja? No, I really meant it honestly. Is that so?
-
Do a normal selection of all the lines of the search regex
-
Open the Replace dialog (
Ctrl + H
) -
Copy/paste the
Replace with :
field -
Tick the
In selection
button, if necessary -
Select the
Regular expression
search mode -
Click on the
Replace All
( Do not use theReplace
button ! )
Best Regards,
guy038
-
Thank you @guy038. I had wondered how FREE-SPACING mode could be useful and what you posted was a good example of how to use it. I was not aware that it also allowed you to insert # style comments into the search expression.
-
Hello, @mkupper and All,
Refer to the this post in order to correctly use the
free-spacing
mode :https://community.notepad-plus-plus.org/post/61100
IMPORTANT :
Multi-lines
free-spacing
regexes, like, for example :(?x-i) ^ \x20 \x20 abc # String 'abc' with LEADING spaceq | # or ^ \x20 \x20 def # String 'def' with LEADING spaces
Works correctly, ONLY IF you click on :
-
The
Find Next
or theCount
button of the Find dialog -
The
Replace
or theReplace All
button of the Replace dialog -
The
Mark All
button of the Mark dialog
It will fail if you click on :
-
The
Find All in Current document
button, of the Find diaog -
The
Find All in All Opened Documents
button, of the Find dialog -
The
Find All
button, of the Find in Files dialog -
The
Find All
button, of the Find in Projects dialog
In addition, it wrongly switches the search mode to the
Extended
mode
Instead, when using these buttons, you’ll have to use, either :
-
A
free-spacing
regex, on a single line, ONLY, as, for example, the regex(?x-i) ^ \x20 \x20 abc | ^ \x20 \x20 def
-
The simple regex
(?-i)^\x20\x20abc|^\x20\x20def
, with all text attached
Refer to my GitHub issue :
https://github.com/notepad-plus-plus/notepad-plus-plus/issues/12673
Best Regards,
guy038
-