I have a vocalized Hebrew text; most letters are followed by one or more combining characters. I would like to replace some of the base characters, leaving the combining characters intact. It seems the only way to search by base character alone is to use \Z, but when I include that in the search pattern, the combining characters are discarded in the substitution operation. Also searching for the base char followed by a range of combining chars \m\%ufb25[\u05b0-\u05bd]* doesn't seem to work.


ﬥְמַֽעַן וְהֽוּא־ﬥָֽךְ כְּסֶֽגֶן בְּאֶרְאֶﬥֵּי־אֵשׁ

This text has three occurrences of wide lamed (U+FB25) which I'd like to replace with regular lamed (U+05DC). Each wide lamed is followed by different combining characters:

  • <ﬥ‎> 64293, Hex fb25, Octal 175445 < ְ> 1456, Hex 05b0, Octal 2660
  • <ﬥ‎> 64293, Hex fb25, Octal 175445 < ָ> 1464, ...5b8, Octal 2670 < ֽ> 1469, Hex 05bd, Octal 2675
  • <ﬥ‎> 64293, Hex fb25, Octal 175445 < ֵ> 1461, ...5b5, Octal 2665 < ּ> 1468, Hex 05bc, Octal 2674

The ideal solution would yield the following with a single substitution:

לְמַֽעַן וְהֽוּא־לָֽךְ כְּסֶֽגֶן בְּאֶרְאֶלֵּי־אֵשׁ׃

Note: I avoided formatting as code blocks, because the difference between wide lamed and its regular counterpart isn't apparent when using a monospace font. (Also it isn't really code, in the conventional sense.)

  • It was easy to solve with Python, which seems to view the text as just a sequence of code points, with no special treatment of combining characters. It's good to know the strenths of each tool. Oct 18 '16 at 13:47

This search pattern seems to work on your sample:


That pattern will match every instance of U+fb25, optionally followed by U+05b0, U+05b8, or U+05b5, optionally followed by U+05bd or U+05bc. Only what precedes \ze is matched so the replacement only affects U+fb25, preserving the combining characters.

For the substitution part:


or simply:

  • It doesn't seem to work for me. Can you explain how/why it would work, and any settings or version dependencies? According to the docs, \ze means "end of match." It isn't obvious to me how that works in this context. Also, can you explain the use of \| inside []? That construct is unfamiliar to me. Oct 18 '16 at 12:05
  • What doesn't work? This is pretty basic and should work in Vim without any setup (tested here with $ vim -u NONE).
    – romainl
    Oct 18 '16 at 12:14
  • I tried with vim -u NONE and it matches only wide lamed without any diacritics. Except for \ze (which you explained), this looks pretty much the same as my failed attempt with \%ufb25[\u05b0-\u05bd]*. I am using Vi IMproved 7.4 (2013 Aug 10, compiled Nov 11 2013 16:04:44). Oct 18 '16 at 12:28
  • Please see my edit and sorry for the brain fart. I stupidly used [foo\|bar] instead of \(foo\|bar\) where \| is used for alternation.
    – romainl
    Oct 18 '16 at 12:46
  • Maybe I should try with a newer version. Oct 18 '16 at 12:48

This site is temporarily in read only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .