2

Say I have this Matlab or Octave char variable:

>> filename = 'my.file.ext'

I want a regexprep command that adds a suffix, say '_old', to the file name before the extension, transforming it into 'my.file_old.ext'.

The following replaces all dots with '_old.':

>> regexprep(filename, '\.', '_old.')
ans =
    'my_old.file_old.ext'

What is a regexprep command that prepends '_old' only to the last dot? (Ideally, if there is no dot (no extension), append '_old' at the very end.)

Thank you in advance!

Felipe Jiménez
  • 453
  • 3
  • 9

2 Answers2

4

If doing it without regular expressions is an option, you can use fileparts as follows:

filename  = 'my.file.ext';
suffix = '_old';
[p, n, e] = fileparts(filename); % path, file, extension; each possibly empty
result = [p, n, suffix, e];

Example in Octave.

Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
1

You may use

regexprep(filename, '^(?:(.*)(\.)|(.*))', '$3$1_old$2')

See the regex demo

Details

  • ^ - start of string
  • (?:(.*)(\.)|(.*)) - a non-capturing group matching either of the two alternatives:
    • (.*)(\.) - Group 1 ($1 backreference refers to the value of the group): any zero or more chars as many as possible and then Group 2 ($2): a dot
    • | - or
    • (.*) - Group 3 ($3): any zero or more chars as many as possible

If an alternative is not matched, the backreference to the capturing group is an empty string. Thus, if (.*)(\.) matches, the replacement is Group 1 + _old + Group 2 value. Else, it is Group 3 + _old (just appending at the end).

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • 1
    Great! Thank you, Wiktor. – Felipe Jiménez Aug 08 '20 at 23:34
  • Sorry, Wiktor, for some reason it works in Octave: >> regexprep('my.file.ext', '^(?:(.*)(\.)|(.*))', '$3$1_old$2') ans = my.file_old.ext but in Matlab (9.6.0.1072779 (R2019a)) it does not: >> regexprep('my.file.ext', '^(?:(.*)(\.)|(.*))', '$3$1_old$2') ans = '$3$1_old$2ext' Any idea why? – Felipe Jiménez Aug 09 '20 at 13:36
  • @FelipeJiménez No idea why, the replacement syntax is the same. – Wiktor Stribiżew Aug 09 '20 at 21:18
  • @wiktor.stribizew Thank you, I posted the Q to MathWork's "Matlab Answers" and will bring feedback here in case you're interested. – Felipe Jiménez Aug 10 '20 at 11:53
  • You can see answer by Walter Roberson here: https://es.mathworks.com/matlabcentral/answers/577600-how-to-correct-unexpected-behavior-of-regexprep (Hope it is ok to link to there.) – Felipe Jiménez Aug 10 '20 at 13:03
  • @FelipeJiménez If the explanation is correct you may simply change the non-capturing group with a capturing one and increment the backreferences, `regexprep(filename, '^((.*)(\.)|(.*))', '$4$2_old$3')` – Wiktor Stribiżew Aug 10 '20 at 21:02
  • No, the explanation seems not ok, since your last command again works in Octave but not in Matlab (where the result is '$4$2_old$3ext'). – Felipe Jiménez Aug 11 '20 at 18:59