• בלוג
  • vim
  • ביטויים רגולאריים וקסמים של וים

ביטויים רגולאריים וקסמים של וים

21/12/2018
vim

בוובינר ביטויים רגולאריים אתמול רציתי להראות דוגמא לביטוי שלוקח שורה כמו זו:

<img src="cat.png" />

והופך אותה לשורה שנראית כך:

<img src="cat-1.png" />

כמובן שב src עצמו יכולה להיות כתובה כל מילה ולכן ביטויים רגולאריים יכולים לתת כאן פיתרון גנרי ומוצלח יותר מאשר אפשרויות אחרות. הבעיה היחידה ש vim לא רצה לשתף פעולה. ההסבר מדוע הוא קסום.

מסתבר של vim יש 4 מצבי עבודה כשמדובר בפיענוח ביטויים רגולאריים. הם נקראים בתרגום שלי: לא קסום בכלל, קצת קסום, קסום במידה וקסום ממש.

למצב לא קסום בכלל אנחנו נכנסים עם התו \V בתחילת הביטוי הרגולארי והוא אומר שכל התווים בביטוי מאבדים את משמעותם המיוחדת, ונצטרך לשים \\ לפני תו כדי להעניק לו משמעות מיוחדת (כולל כל התווים שבדרך כלל בביטוי רגולארי כן היתה להם משמעות מיוחדת). לכן כדי למצוא שתי ספרות בטקסט במצב לא קסום בכלל נכתוב את החיפוש:

/\V\[0-9]\[0-9]

עדיין אפשר להשתמש בקיצור \d כך שגם החיפוש הזה יעבוד:

/\V\d\d

למצב קצת קסום אנחנו נכנסים עם \M בתחילת הביטוי ומצב זה ממש דומה ל"לא קסום בכלל" מלבד התווים ^ ו $ שלא צריכים שתכתבו \\ לפניהם.

למצב קסום אנחנו נכנסים עם \m בתחילת הביטוי. מצב זה מזכיר מאוד את grep ובו רוב הסימנים המיוחדים יעבדו בלי \\ אבל עדיין יהיו מספר סימנים מיוחדים שכן יצטרכו \\ לפניהם לדוגמא +, ? ו {}.

ולמצב קסום ממש אנחנו נכנסים עם \v ושם רוב מוחלט של התווים יקבלו משמעות מיוחדת ונצטרך סימן \\ כדי לתת לתווים משמעות "רגילה".

בחזרה לדוגמא מתחילת הפוסט הביטוי הראשון שניסיתי לכתוב בוובינר היה:

:s/\vsrc="(\w+)\.(\w+)"/src="\1-1.\2"/

אבל לא נמצא אף מופע. עכשיו שלמדנו על המשמעות של Very Magic קל לראות שהבעיה היא בסימן השווה. שווה בביטוי רגולארי של וים הוא סימן שקול לסימן שאלה, ולכן בלי סימן ה \\ הוא קיבל את משמעותו המיוחדת של שאומרת שה c שלפניו מופיע פעם אחת או אפס פעמים.

התיקון הכי פשוט יהיה להוסיף \\ לפני סימן השווה ואז נקבל את הביטוי הבא שעובד:

:s/\vsrc\="(\w+)\.(\w+)"/src="\1-1.\2"/

אגב עכשיו שזה מאחורינו בואו נראה את הגירסאות המתאימות של הביטוי גם במצבי הקסם האחרים:

:s/\Vsrc="\(\w\+\).\(\w\+\)"/src="\1-1.\2"/
:s/\msrc="\(\w\+\).\(\w\+\)"/src="\1-1.\2"/
:s/\Msrc="\(\w\+\).\(\w\+\)"/src="\1-1.\2"/

למידע נוסף על כל הסימנים וההשפעות של מצבי הקסם ב vim מוזמנים לקרוא בתיעוד כאן:

http://vimdoc.sourceforge.net/htmldoc/pattern.html#pattern