Регулярное выражение для соответствия символу Юникод, за исключением случаев, когда используется в конце слова - PullRequest
0 голосов
/ 22 мая 2018

Мне нужно найти и заменить все вхождения (за исключением конца слова) определенного символа в связке текста RTL.У меня проблемы с поиском или пониманием решения регулярных выражений, которое работает.

Я пробовал (?<=\w)ی(?=\w), ی(?=\w) и (?<=\w)ی, но не могу найти ничего подходящего.Другие решения, использующие \b или \w, похоже, возвращают больше, чем просто символ ی‍.

Например, я хотел бы найти и заменить 'in' в следующих словах

گیر
غیبت
قیمت
یرغال

но не в этих словах

کسی
کمی

Может кто-нибудь предложить решение, которое я мог бы использовать с sed в bash или JavaScript?

Примечание: эти слова встречаются в большом потоке текста, а не в виде отдельных строк или строк.

Редактировать: Вот еще один пример использования английских слов,(Надеюсь, решение будет работать так же с текстом RTL или LTR).

Я хотел бы найти и заменить 'x' в этих словах:

axe xylophone exec

Но не ,

borax, anthrax

Спасибо!

Ответы [ 5 ]

0 голосов
/ 22 мая 2018

Разве это не все, что вам нужно?

$ sed 's/x\([^[:space:]]\)/Y\1/g' file
aYe Yylophone eYec
borax anthrax

или в зависимости от того, что определяет и / или разделяет ваши "слова", может быть одно из следующих:

$ sed 's/x\([[:alpha:]]\)/Y\1/g' file
aYe Yylophone eYec
borax anthrax

$ sed 's/x\([^[:punct:][:space:]]\)/Y\1/g' file
aYe Yylophone eYec
borax anthrax

или что-то другоедругая комбинация классов символов определяет либо вашу концепцию составного слова, либо разделителя слов.Также с GNU sed для \w означает word-constituent character:

$ sed 's/x\(\w\)/Y\1/g' file
aYe Yylophone eYec
borax anthrax
0 голосов
/ 22 мая 2018

Благодаря предложению @ revo у меня теперь есть хорошее решение JavaScript:

str.replace(/\u06cc(?=[\u0200-\u06ff])/g, '\u064A')

, где \u06cc - символ, который я хочу заменить (кроме случаев, когда он встречается в концеслова) и \u064A - это символ, которым я его заменяю.

edit: Revo также дал отличное решение, использующее Perl.Не сед, но делает именно то, что я хотел. Этот парень - очень полезная легенда.Спасибо !!

perl -pCSD -i.bak -e 's/\x{06cc}(?=[\x{0600}-\x{06ff}])/\x{064a}/g' text-file.txt

06cc - это символ Юникода, подлежащий замене.064a это то, чем он заменяет.

0 голосов
/ 22 мая 2018

sed поддерживает POSIX, который по сравнению с современными регулярными выражениями имеет ограниченные возможности.Приведенный ниже обходной путь использует JS, но наверняка будет переносимым для sed (некоторые гуру bash / sed могут это сделать):

\u06cc(?=[\u0600-\u06ff])

Соответствует букве ی, за которой следует другая буква на арабском языкеблок (0600 - 06ff)

var str = `گیر
غیبت
قیمت
یرغال
کسی
کمی
`;

str.split(/\n/).forEach(function(word){
  if (/\u06cc(?=[\u0600-\u06ff])/.test(word)) {
    console.log(word);
  }
})
0 голосов
/ 22 мая 2018

Вы можете сделать это, используя \ B. Если вы хотите, чтобы все символы, кроме случаев, когда он появляется в конце слова, вы используете \ B \ B, пример: это будет соответствовать всем символам "e", кроме случаев, когда это последнийсимвол:

t e st

найдено e r

s e e

если вы хотите заменить этот же символ во всех словах, кроме слов, оканчивающихся на этот символ, вы можете использовать:. * [^ E] $, чтобы получить все эти слова, а затем применить новое регулярное выражение, чтобы найти все«е» слова.Пример:

Шаг 1:. * [^ E] $

тест

основатель

см.


Шаг 2: e

t e st

найдено e r

0 голосов
/ 22 мая 2018

Для вашего примера LTR вы можете использовать x\B - литерал x, а затем маркер "не граница слова".

...