2015-06-16 43 views
0

如果文件中的單詞匹配某些關鍵字/名稱,我試圖做HTML突出顯示。然而,有時候關鍵詞的一部分也存在,Perl會再次匹配它。如何在搜索和替換過程中讓perl跳過某些單詞

例如,我有以下關鍵詞

  1. KY SPINE & REHAB - 當發現與它周圍的方括號
  2. SPINE更換 - 發現與它周圍的圓括弧
  3. REHAB更換時 - 當發現圓括號代替它周圍

一旦它匹配KY SPINE & REHAB,我想要阻止它匹配SPINEREHAB

這就是我現在得到的。我不能給HTML的例子,因爲我不知道如何顯示HTML標記,因爲這個網站翻譯它,只顯示文本。實際上,我試圖用不同的顏色來突出顯示這些關鍵字,這些關鍵字來自於它們來自哪一組。

我現在得到:

[KY (SPINE) & (REHAB)] 

我要的是:

[KY SPINE & REHAB] 

如何讓我的Perl跳過的話,在做搜索和替換?

我有數百萬條記錄,我必須這樣做,即使並行處理速度也不是那麼快。所以,代碼高效的建議將不勝感激。

作爲更新,我有數百個關鍵字,任何關鍵字可能是另一個關鍵字的子集。所以對其進行硬編碼是不實際的。我正在尋找解決方案,perl可以跳過方括號內的字符串,這樣就不會發生進一步的替換。

+0

歡迎堆棧溢出。看看http://stackoverflow.com/editing-help並瞭解問題和答案的格式。我冒昧地讓它更具可讀性。還請閱讀[問],然後添加您編寫的代碼以獲取當前輸出和一些樣本數據。 – simbabque

回答

-1

這爲我工作

s/(KY SPINE & REHAB|SPINE|REHAB)/[$1]/g 

希望它會爲你工作,要麼

編輯:

這是爲我工作一個完整的代碼。可以將它用於您的案例或任何其他自定義替換任何字符串。這可能不是一個很酷的班輪,但它的工作原理。希望它更適合您的需求。

use strict; 
use warnings; 

my ($new, $last, $offset, $length, $replace); 

while(<DATA>) { 
    $new = ''; 
    $last = 0; 
    while ($_ =~ m/KY SPINE & REHAB|SPINE|REHAB/g) { 
     $offset = $-[0]; 
     if ($& eq 'KY SPINE & REHAB') { 
      $replace = '[' . $& . ']'; 
     } 
     if ($& eq 'SPINE') { 
      $replace = '(' . $& . ')'; 
     } 
     if ($& eq 'REHAB') { 
      $replace = '(' . $& . ')'; 
     } 
     $length = $offset - $last; 
     $new .= substr($_, $last, $length) . $replace; 
     $last = $+[0]; 
    } 
    $length = length($_) - $last; 
    $new .= substr($_, $last, $length); 
    print $new; 
} 

__DATA__ 
lorem ipsum KY SPINE & REHAB dolor sit amet SPINE consectetur adipiscing elit REHAB sed do eiusmod tempor incididunt ut labore et dolore magna aliqua sit amet SPINE consectetur adipiscing elit REHAB sed do eiusmod tempor 
KY SPINE & REHAB dolor sit amet SPINE consectetur adipiscing elit REHAB sed do eiusmod tempor incididunt ut amet SPINE consectetur adipiscing elit REHAB sed do eiusmod tempor adipiscing elit REHAB sed do eiusmod tempor 
lorem ipsum KY SPINE & REHAB dolor sit amet SPINE consectetur adipiscing elit REHAB sed do eiusmod tempor incididunt ut labore et dolore magna aliqua sit amet SPINE consectetur adipiscing elit REHAB sed do eiusmod tempor 
SPINE sit amet SPINE consectetur REHAB 
SPINE 
sit amet SPINE consectetur KY SPINE & REHAB REHAB 
+0

嗨亞歷克斯 - 感謝您的回答。也許我沒有正確地問它。我不能在這裏做'OR(|)',因爲我需要用不同的方式替換這些單詞。所以我需要做多次傳球。我已經更新了這個問題。 –

+0

@LeslieFrancis嗨Leslie我修復了代碼。它應該現在適合你的情況。 –

1

如果這些是你想突出,那麼唯一的三個階段,這將做它爲您

perl -i -pe's/(KY SPINE & REHAB|SPINE|REHAB)/$1 =~ tr/&// ? "[$1]" : "($1)"/eg' myfile 
0

如何:

while(<DATA>) { 
    chomp; 
    s/(KY SPINE & REHAB)/[$1]/; 
    s/(SPINE(?!.*REHAB)|(?<!SPINE &)REHAB)/($1)/; 
    say; 
} 

__DATA__ 
KY SPINE & REHAB - when found replace with square brackets around it 
SPINE - when found replace with round brackets around it 
REHAB - when found replace with round brackets around it 

輸出:

[KY SPINE & REHAB] - when found replace with square brackets around it 
(SPINE) - when found replace with round brackets around it 
(REHAB) - when found replace with round brackets around it 
+0

這將失敗的記錄像'xxx xxx SPINE xxx xxx REHAB xxx'。什麼是「chomp」? – Borodin

+0

@Borodin:是的,但它適用於給定的例子。 chomp是爲了避免輸出雙重換行。 – Toto

+0

OP沒有顯示任何示例數據。當你不想打印額外的換行符時,'print'是'say'的一個有用的替代方法。 – Borodin

相關問題