0

I need your kind help on writing a regular expression for the following situation.

Consider the following first word sequence:

Criteria A xxx xxx xxx Table1
Criteria A xxx xxx xxx Table2
Criteria A xxx xxx xxx Table3
Criteria A xxx xxx xxx Table4
Criteria A xxx xxx xxx Table5
Criteria A xxx xxx xxx Table6
Criteria A xxx xxx xxx Table7
Criteria A xxx xxx xxx Table8
Criteria A xxx xxx xxx Table9

Criteria B xxx xxx xxx Table10
Criteria B xxx xxx xxx Table11
Criteria B xxx xxx xxx Table12
Criteria B xxx xxx xxx Table13
Criteria B xxx xxx xxx Table14
Criteria B xxx xxx xxx Table15
Criteria B xxx xxx xxx Table16
Criteria B xxx xxx xxx Table17
Criteria B xxx xxx xxx Table18

Criteria C xxx xxx xxx Table19
Criteria C xxx xxx xxx Table20
Criteria C xxx xxx xxx Table21
Criteria C xxx xxx xxx Table22
Criteria C xxx xxx xxx Table23
Criteria C xxx xxx xxx Table24
Criteria C xxx xxx xxx Table25
Criteria C xxx xxx xxx Table26
Criteria C xxx xxx xxx Table27

I would like to change them in the following second sequence:

Criteria A xxx xxx xxx Table1
Criteria A xxx xxx xxx Table2
Criteria A xxx xxx xxx Table3
Criteria B xxx xxx xxx Table4
Criteria B xxx xxx xxx Table5
Criteria B xxx xxx xxx Table6
Criteria C xxx xxx xxx Table7
Criteria C xxx xxx xxx Table8
Criteria C xxx xxx xxx Table9

Criteria A xxx xxx xxx Table10
Criteria A xxx xxx xxx Table11
Criteria A xxx xxx xxx Table12
Criteria B xxx xxx xxx Table13
Criteria B xxx xxx xxx Table14
Criteria B xxx xxx xxx Table15
Criteria C xxx xxx xxx Table16
Criteria C xxx xxx xxx Table17
Criteria C xxx xxx xxx Table18

Criteria A xxx xxx xxx Table19
Criteria A xxx xxx xxx Table20
Criteria A xxx xxx xxx Table21
Criteria B xxx xxx xxx Table22
Criteria B xxx xxx xxx Table23
Criteria B xxx xxx xxx Table24
Criteria C xxx xxx xxx Table25
Criteria C xxx xxx xxx Table26
Criteria C xxx xxx xxx Table27

Please do note that in my actual text, I actually have multiple (consistent) lines for each line above:

Criteria A xxx xxx xxx Table1
bunch of text
bunch of unique text
another bunch of text

Criteria A xxx xxx xxx Table2
bunch of text
bunch of unique text
another bunch of text

{and so on}

I also would like to know the regular expression if the situation happens in reverse (I want to change from the second sequence to the first sequence).

3
  • 1
    Does the text need to move or only the labels A,B,C? Since the table numbers don’t change it’s a bit hard to tell exactly what needs to happen. – D. Ben Knoble Apr 3 at 14:01
  • @D.BenKnoble The text must not move, only the labels are changed. The table numbers are already fixed, and the sequence continues to Table 1296 in my original text. So, sorting is not an option, since the sequence has to be fixed for all lines. For each 'paragraph' I can tell you that the number of lines and the sequence of it are all identical (the contents are only slightly different for every 27 tables), but all I need is to change the sequence of the criteria label. – Nampuna D. Gultom Apr 3 at 23:40
  • @D.BenKnoble Also, there are no other criteria labels. Just either A, B, or C for the entire 1,296 tables. – Nampuna D. Gultom Apr 3 at 23:43
2

In the first case, I would probably just adjust the table numbers and do :sort n to sort by number (this doesn't work if there are numbers before the table number; in that case, something like :sort n /\d*$/ ought to work.). To adjust the table numbers, <C-x> and <C-a> with a count, which are dot-repeatable, are helpful.

After the sort, you just have to manually touch up the blank lines. For a small example this wasn't worth automating.

Note that this moves the whole line, not just the A/B/C.

If you want to do this with paragraphs, I suggest the following approach:

  • merge each paragraph into a single line, but save the positions of the newlines (we'll do this by picking a character like @ that doesn't appear in the text and using it to separate lines)
  • adjust table numbers and sort, again
  • re-break the paragraphs

Altogether, I would do it with these steps:

  • qqq clear q register for a recursive macro
  • ggq start recording at top of document
  • vip:-substitute/\n/@/g<CR> join the paragraph with @ signs (note that the command line will say something like :'<,'>-substitute/… which is intentional)
  • }j@q move to the next paragraph and execute the macro recursively
  • q stop recording
  • @q run it; should process the whole file

Now, adjust and sort as before; then, :%substitute/@/\r/g.

0

Here's an approach to only change the criteria labels (I haven't gotten undo yet, but u works). The idea is consider the line-number modulo 10 to lookup the name to replace with:

let g:names = repeat(['A'], 3) + repeat(['B'], 3) + repeat(['C'], 3)

global/^Criteria/execute 'normal! 0Wcw'.get(g:names, (line('.') - 1) % 10)

For paragraphs, I would join them as in the other answer and then do this, or adjust the names lookup and modulo based on your exact numbers.

I thought this would be easy to port to awk and run :%!awk … using (NR - 1) % 10 == 0 { $1 = 'A' } for example, but I keep getting a division-by-zero error from awk, even just on the sample program awk '{printf NR % 10}', so not sure what's going on there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.