2013-06-23 27 views
14

Tôi có một tập hợp các chuỗi mà tôi cần phải thay thế, nhưng tôi cần phải giữ cho trường hợp của các chữ cái. cả hai từ đầu vào và các từ đầu ra có cùng độ dài.Thay thế văn bản nhưng giữ trường hợp

Ví dụ, nếu tôi cần phải thay thế "abcd" với "qwer", sau đó những điều sau đây sẽ xảy ra:

"AbcD" translates to "QweR" 
"abCd" translates to "qwEr" 

và vân vân.

Ngay bây giờ tôi đang sử dụng của JavaScript replace, nhưng chữ in hoa bị mất trên bản dịch.

r = new RegExp("(" + 'asdf' + ")" , 'gi'); 
"oooAsdFoooo".replace(r, "qwer"); 

Mọi trợ giúp sẽ được đánh giá cao.

+0

Chuỗi đích và thay thế được biết hoặc chúng sẽ là động? – pvnarula

+0

Xin lỗi, tôi không hiểu câu hỏi của bạn. Nhưng đây là trường hợp: Tôi đang sao chép một văn bản do người dùng nhập. Tôi có một danh sách các quy tắc, như "ca" sao chép thành "kb", nhưng tôi cần giữ các chữ cái viết hoa, vì vậy "cA" chuyển thành "kB". –

+1

tôi sẽ làm điều đó trong 2 bước, đầu tiên "oooAsdFoooo" .search (r) mà trả về chỉ mục và sau đó xử lý các trường hợp. Nhưng tôi sẽ được kích thích nếu có một cách nào đó với một regex chỉ – bert

Trả lời

5

Dưới đây là một helper:

function matchCase(text, pattern) { 
    var result = ''; 

    for(var i = 0; i < text.length; i++) { 
     var c = text.charAt(i); 
     var p = pattern.charCodeAt(i); 

     if(p >= 65 && p < 65 + 26) { 
      result += c.toUpperCase(); 
     } else { 
      result += c.toLowerCase(); 
     } 
    } 

    return result; 
} 

Sau đó, bạn có thể chỉ:

"oooAsdFoooo".replace(r, function(match) { 
    return matchCase("qwer", match); 
}); 
+1

Thật tuyệt vời nhưng chỉ hoạt động với ASCII. :) – Tomalak

+2

@Tomalak: Nếu cần, thay đổi 'p> = 65 && p <65 + 26' thành' UPPERCASE.test (p) ', thay đổi' charCodeAt' thành 'charAt' và xác định' var UPPERCASE =/[anyletters ] /; '. – Ryan

+0

Hoặc có thể trường hợp 'toLocale {Upper, Lower }'. – Ryan

1
String.prototype.translateCaseSensitive = function (fromAlphabet, toAlphabet) { 
    var fromAlphabet = fromAlphabet.toLowerCase(), 
     toAlphabet = toAlphabet.toLowerCase(), 
     re = new RegExp("[" + fromAlphabet + "]", "gi"); 

    return this.replace(re, function (char) { 
     var charLower = char.toLowerCase(), 
      idx = fromAlphabet.indexOf(charLower); 

     if (idx > -1) { 
      if (char === charLower) { 
       return toAlphabet[idx]; 
      } else { 
       return toAlphabet[idx].toUpperCase(); 
      } 
     } else { 
      return char; 
     } 
    }); 
}; 

"AbcD".translateCaseSensitive("abcdefg", "qwertyu") 

sẽ trở lại:

"QweR" 
+1

Điều này thay thế các nhân vật cá nhân mặc dù - câu hỏi ban đầu là nói về việc thay thế các chất nền.Trong exmaple của bạn, chuỗi đầu vào không chứa "abcdefg", vì vậy không có gì nên được thay thế. – jcsanyi

+0

@jcsanyi Hm. Tôi không hiểu theo cách đó. Nhưng có khả năng là bạn nói đúng. – Tomalak

1

Bạn có thể tạo thay thế chức năng của riêng bạn như

if(!String.prototype.myreplace){ 
String.prototype.myreplace = (function(obj){ 
    return this.replace(/[a-z]{1,1}/gi,function(a,b){ 
     var r = obj[a.toLowerCase()] || a; 
     return a.charCodeAt(0) > 96? r.toLowerCase() : r.toUpperCase(); 
    }); 
}); 
} 

này có trong một đối tượng mà các bản đồ chữ khác nhau. và nó có thể được gọi như sau:

var obj = {a:'q',b:'t',c:'w'}; 

    var s = 'AbCdea'; 
    var n = s.myreplace(obj); 
    console.log(n); 

Điều này có nghĩa là bạn có thể chuyển các đối tượng khác nhau với ánh xạ khác nhau nếu cần thiết. Dưới đây là một ví dụ đơn giản fiddle hiển thị ví dụ (lưu ý đối tượng là tất cả chữ thường nhưng chính hàm đó cũng xem xét trường hợp của chuỗi đó)

0

Mở rộng câu trả lời của Ryan O'Hara, giải pháp dưới đây tránh sử dụng charCodes và các vấn đề có thể gặp phải khi sử dụng chúng. Nó cũng đảm bảo sự thay thế hoàn tất khi các chuỗi có độ dài khác nhau.

function enforceLength(text, pattern, result) { 
    if (text.length > result.length) { 
    result = result.concat(text.substring(result.length, text.length)); 
    } 

    if (pattern.length > text.length) { 
    result = result.substring(0, text.length); 
    } 

    return result; 
} 

function matchCase(text, pattern){ 
    var result = ''; 

    for (var i =0; i < pattern.length; i++){ 
    var c = text.charAt(i); 
    var p = pattern.charAt(i); 

    if(p === p.toUpperCase()) { 
     result += c.toUpperCase(); 
    } else { 
     result += c.toLowerCase(); 
    } 
    } 
    return enforceLength(text, pattern, result); 
} 
1

Điều này sẽ thay thế trong khi vẫn giữ nguyên trường hợp. Vui lòng cho tôi biết nếu có ai phát hiện bất kỳ sai sót nào trong giải pháp này. Tôi hi vọng cái này giúp được. Cảm ơn bạn!

function myReplace(str, before, after) { 

     var match=function(before,after){ 
     after=after.split(''); 
     for(var i=0;i<before.length;i++) 
      { 

      if(before.charAt(i)==before[i].toUpperCase()) 
       { 
       after[i]=after[i].toUpperCase(); 
       } 
      else if(before.charAt(i)==before[i].toLowerCase()) 
       { 
       after[i]=after[i].toLowerCase(); 
       } 
      return after.join(''); 
      } 

     }; 
      console.log(before,match(before,after)); 
      str =str.replace(before,match(before,after)); 


     return str; 
    } 

    myReplace("A quick brown fox jumped over the lazy dog", "jumped", "leaped"); 
Các vấn đề liên quan