2010-03-23 10 views
6

Potrzebuję znaleźć najbardziej efektywny sposób dopasowywania wielu wyrażeń regularnych do pojedynczego bloku tekstu. Aby dać przykład, co muszę, rozważmy blok tekstu:Zastępowanie wielu wzorców w bloku danych

„Hello World jaki piękny dzień”

Chcę zastąpić Witam z „pa” i „świat” z Wszechświata. Zawsze mogę to zrobić w pętli, używając funkcji podobnych do String.replace dostępnych w różnych językach.

Mogę jednak mieć duży blok tekstu z wieloma wzorami ciągów, które muszę dopasować i zamienić.

Zastanawiam się, czy mogę użyć Wyrażeń regularnych, aby zrobić to sprawnie, czy też muszę używać Parsera takiego jak LALR.

Potrzebuję zrobić to w JavaScript, więc jeśli ktoś wie, narzędzia, które mogą to zrobić, byłoby to docenione.

Odpowiedz

6

można przekazać funkcję wymienić:

var hello = "Hello World what a beautiful day"; 
hello.replace(/Hello|World/g, function ($0, $1, $2) // $3, $4... $n for captures 
{ 
    if ($0 == "Hello") 
     return "Bye"; 
    else if ($0 == "World") 
     return "Universe"; 
}); 

// Output: "Bye Universe what a beautiful day"; 
+0

Tylko uwaga, Andy E: Musisz ')' 'zanim twój;' w ostatnim wierszu :) –

+0

@smotchkkiss: Tak, zauważyłem, że kiedy pisałem komentarz na dole i zupełnie o tym zapomniałem, zanim skończyłem! Dzięki :-) –

+0

Dzięki, to jest naprawdę pomocne. Jednakże, czy mecze regex są ograniczone do 1 $. $ 9, czy też możemy mieć 10 $, 11 $ itd. ... – VikrantY

10

Edycja

6 lat po moim oryginalnym odpowiedzi (poniżej) chciałbym rozwiązać ten problem inaczej

function mreplace (replacements, str) { 
 
    let result = str; 
 
    for (let [x, y] of replacements) 
 
    result = result.replace(x, y); 
 
    return result; 
 
} 
 

 
let input = 'Hello World what a beautiful day'; 
 

 
let output = mreplace ([ 
 
    [/Hello/, 'Bye'], 
 
    [/World/, 'Universe'] 
 
], input); 
 

 
console.log(output); 
 
// "Bye Universe what a beautiful day"

To jest jak olbrzymia reklama vantage nad poprzednią odpowiedzią, która wymagała dwukrotnego napisania każdego meczu. Daje również indywidualną kontrolę nad każdym meczem. Na przykład:

function mreplace (replacements, str) { 
 
    let result = str; 
 
    for (let [x, y] of replacements) 
 
    result = result.replace(x, y); 
 
    return result; 
 
} 
 

 
let input = 'Hello World what a beautiful day'; 
 

 
let output = mreplace ([ 
 
    //replace static strings 
 
    ['day', 'night'], 
 
    // use regexp and flags where you want them: replace all vowels with nothing 
 
    [/[aeiou]/g, ''], 
 
    // use captures and callbacks! replace first capital letter with lowercase 
 
    [/([A-Z])/, $0 => $0.toLowerCase()] 
 

 
], input); 
 

 
console.log(output); 
 
// "hll Wrld wht btfl nght"


Original odpowiedzi

Andy E „s odpowiedź może być modyfikowana, aby dodanie definicji zamienne łatwiejsze.

var text = "Hello World what a beautiful day"; 
text.replace(/(Hello|World)/g, function ($0){ 
    var index = { 
    'Hello': 'Bye', 
    'World': 'Universe' 
    }; 
    return index[$0] != undefined ? index[$0] : $0; 
}); 

// "Bye Universe what a beautiful day"; 
+0

Dzięki Andy/smotchkiss, oboje całkowicie posortowaliście mój problem i unikaliście pisania własnego algorytmu, wielokrotnego zastępowania. – VikrantY

+2

Prawdopodobnie nie powinieneś ponownie tworzyć obiektu odnośnika dla każdego wywołania funkcji zastępczej, ale zamiast tego mieć go na zewnątrz? – Phrogz

1

Ulepszony odpowiedź:

var index = { 
    'Hello': 'Bye', 
    'World': 'Universe' 
}; 

var pattern = ''; 
for (var i in index) { 
    if (pattern != '') pattern += '|'; 
    pattern += i; 
} 

var text = "Hello World what a beautiful day"; 
text.replace(new RegExp(pattern, 'g'), function($0) { 
    return index[$0] != undefined ? index[$0] : $0; 
}); 
+0

To stare pytanie ze starymi odpowiedziami.Myślę, że oferujesz dobrą poprawę, ale możesz rozszerzyć jeszcze więcej mocy, nie zmuszając ich do wejścia przez konstruktor "RegExp" i automatycznie dodając flagę "g". –

Powiązane problemy