2

im working on a translation project and i need to modify some characters at the end for example if user types words like:

typed word: "yilanin" => target word (what i want) :"yilaNG"

"suyunin" => "suyuNG"

"kalinin" => "kaliNG"

"batinin" => "batiNG"

etc etc...

But i have a problem: i don't want to modify "nin" characters if they are at the middle or at the beginning of a word like:

"kinindan*"" => **"kinindan"

"sininteki"" => "sininteki"

"nin" => "nin"

"ninkisi" => "ninkisi"

etc etc...

i mean every "xxxnin" to "xxxNG",

"xxxninxxx" to "xxxninxxx"(no modification),

"nin" to "nin" (no modification)...

i tried to explain my problem very clearly and bascially i hope you understand...

$(document).ready(function(){

$("#ta_1").keyup(function(event) {

  var text2 = $(this).val();
  
  text2 = text2.replace(/([abcçdefgğhıijklmnoöprsştuüvyzABCÇDEFGHIİJKLMNOÖPRSTUÜVYZ])nin$/g, '$1NG');
  
  $("#ta_1").val(text2);
  
});
  
});
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="utf-8" />
  
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  
</head>

<body>
  
  <textarea id="ta_1" rows="5" cols="28"></textarea>

</body>
  
</html>
pinug
  • 161
  • 1
  • 2
  • 9

4 Answers4

3

You need to track two events: keyup (to track text input continuation) and blur (to check for the string input end). Then, use 2 different replacements:

$(document).ready(function(){
 $("#ta_1").on("keyup blur", function(event) {
    var text2 = $(this).val();
    if (event.type !== "blur") { // Trigger only on keyup
 text2 = text2.replace(/([a-zA-ZçğıöşüÇİÖÜ])nin\b(?![a-zA-ZçğıöşüÇİÖÜ])([\s\S])/g, '$1NG$2');
    }
    else { // we have blur
   text2 = text2.replace(/([a-zA-ZçğıöşüÇİÖÜ])nin$/, '$1NG');
    }
    $("#ta_1").val(text2);
 })
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="ta_1" rows="5" cols="28"></textarea>

The keyup event will check for an already input word containing (I guess) Turkish word - ([a-zA-ZçğıöşüÇİÖÜ])nin\b(?![a-zA-ZçğıöşüÇİÖÜ])([\s\S]) - followed with some character that will serve as a word boundary.

The blur event will check for a nin at the end of the whole string only, and perform the replacement if necessary.

Update:

Here is another approach: replace while typing and if another character is typed, revert. However, this approach won't work if several character combinations can be replaced with one and the same replacement pattern (it will be unclear what string to restore then):

$(document).ready(function(){
 $("#ta_1").on("keyup", function(event) {
    var text2 = $(this).val();
    // Replace nin to NG in general
 text2 = text2.replace(/([a-zA-ZçğıöşüÇİÖÜ])nin\b(?![a-zA-ZçğıöşüÇİÖÜ])/g, '$1NG');
   // Restore nin from NG
    text2 = text2.replace(/([a-zA-ZçğıöşüÇİÖÜ])NG(?=[a-zA-ZçğıöşüÇİÖÜ])/g, '$1nin')
    $("#ta_1").val(text2);
 })
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="ta_1" rows="5" cols="28"></textarea>
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • thank you so much sir thank you for your interest and your information sir it is very important for me :) – pinug Apr 18 '16 at 08:57
  • Not only, there must be at least one more character / focus lose to trigger a replacement. Since the text input is live, you do not have any opportunity to track a "whole word" with `\b` or anything. That is why I suggest using 2 events to check for the input state. With the Unicode letters in place, `\b` is useless :( – Wiktor Stribiżew Apr 18 '16 at 09:02
2

Would something like this work?

text.replace(/([\s\S])nin\b(?![çğıöşüÇİÖÜ])/, '$1NG');

\b matches a word boundary position such as whitespace, punctuation, or the start/end of the string.

?![çğıöşüÇİÖÜ] negative lookahead to specify no match if any of the specified characters are found.

var stringArr = ['suyunin', 'kalinin', 'batinin', 'kinindan', 'sininteki', 'nin', 'ninkisi', 'xxxnin', 'xxxninxxx', 'nin', 'Kalininü'];

var generated = document.getElementById('generated');

for (var i = 0; i < stringArr.length; i++) {
  var newStr = stringArr[i].replace(/([\s\S])nin\b(?![çğıöşüÇİÖÜ])/, '$1NG');

  var li = document.createElement('li');

  li.appendChild(document.createTextNode(newStr));
  generated.appendChild(li);
}
#generated {
  color: red;
}
<!DOCTYPE html>
<html>

<body>
  Array List:
  <br>['suyunin', 'kalinin', 'batinin', 'kinindan', 'sininteki', 'nin', 'ninkisi', 'xxxnin', 'xxxninxxx', 'nin'];
  <br>Generated List:
  <br>
  <span id='generated'></span>
</body>

</html>
timolawl
  • 5,434
  • 13
  • 29
  • i tried on stackoverflows code snippet tool but not working :/ – pinug Apr 18 '16 at 08:29
  • 1
    I believe you don't need the /g (global) for that :) – JF-Mechs Apr 18 '16 at 08:29
  • thanks, I have removed the `/g` and updated the formula. Try now. – timolawl Apr 18 '16 at 08:33
  • @timolawl i tested on stackoverflows code snippet tool but it is not working :/ can you send me a jsfiddle example please ? :/ – pinug Apr 18 '16 at 08:37
  • i don't know why it is not working on you but I tested timolawl answers on fiddle and it's working fine :) – JF-Mechs Apr 18 '16 at 08:37
  • @JF-Mechs can you send me a jsfiddle example on this code(the code that i posted) please ?? :/ – pinug Apr 18 '16 at 08:43
  • Okay! Run the code and compare the alerts to the array. – timolawl Apr 18 '16 at 08:43
  • @timolawl perfect sir but i don't know how to insert it on my code(the code that i posted) because even i insert your code it is not working sir maybe i had some mistakes,,, :/ – pinug Apr 18 '16 at 08:48
  • 1
    Note that `\b` will find `nin` in `Kalininü` ([demo](https://regex101.com/r/kF9cD5/1)). Anyway, the regex `(?!^nin)(nin\b)` could be written in a cleaner way. Like `([\s\S])(nin\b)` – Wiktor Stribiżew Apr 18 '16 at 09:06
  • Thank you that was really helpful. I was working with the `[\s\S]` but it didn't occur to me just to use it without the lookahead. – timolawl Apr 18 '16 at 09:17
2

This should work

(?!^nin)(nin$)

Regex Demo

JS Code

var re = /(?!^nin)(nin$)/gm; 
var str = 'suyunin\nabcninshs\nning\ngnin\nning\nkinindan*\nsininteki\nnin\nninkisi';
var subst = 'NG'; 
var result = str.replace(re, subst);
document.writeln(result)

JSFiddle Demo

Ideone Demo

rock321987
  • 10,942
  • 1
  • 30
  • 43
2

Try this

(\w)(nin)\b

Regex demo

$(document).ready(function(){
//setup before functions
var typingTimer;                //timer identifier
var doneTypingInterval = 1000;  //time in ms, 1 second for example
var $input = $('#myInput');

//user is "finished typing," do something
function doneTyping () {
  //do something
}
$("#ta_1").keyup(function(event) {

  var text2 = $(this).val();
  var re = /(\w)(nin)([^a-zA-Z])/g; 
var subst = '$1NG$3'; 
  text2 = text2.replace(re, subst);
var re = /(\w)(NG)(\w)/; 
var subst = '$1nin$3'; 
 text2 = text2.replace(re, subst);
  $("#ta_1").val(text2);
  clearTimeout(typingTimer);
  typingTimer = setTimeout(doneTyping, doneTypingInterval);
});
$("#ta_1").keydown(function(event) {
    clearTimeout(typingTimer);
}); 
function doneTyping () {
  var text2 = $("#ta_1").val();
  var re = /(\w)(nin)\b/g; 
var subst = '$1NG'; 
  text2 = text2.replace(re, subst);
  $("#ta_1").val(text2);
}     
});
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="utf-8" />
  
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  
</head>

<body>
  
  <textarea id="ta_1" rows="5" cols="28"></textarea>

</body>
  
</html>
Tim007
  • 2,557
  • 1
  • 11
  • 20
  • @pinug what is output for kinindan? – Tim007 Apr 18 '16 at 08:43
  • it outs "kiNGdan" it shouldn't modify it if its in the middle :/ – pinug Apr 18 '16 at 08:46
  • 1
    @pinug check update, must type enter or spacebar for replacing word. – Tim007 Apr 18 '16 at 08:52
  • ouups user have to press enter or space then sir,,it is not good for me :/ – pinug Apr 18 '16 at 08:55
  • This won't work if `nin` is followed with punctuation: `ddddnin.`. – Wiktor Stribiżew Apr 18 '16 at 09:00
  • @pinug check update. I add these code http://stackoverflow.com/questions/4220126/run-javascript-function-when-user-finishes-typing-instead-of-on-key-up So after 1 second `kinin` will replace to `kinNG`. If they continue typing `kinindan`, `kinin` won't be replace. – Tim007 Apr 18 '16 at 09:13
  • @Tim007 oh my god it is very useful for me sir maybe if we reduce to 30 milliseconds it will be better ? – pinug Apr 18 '16 at 09:19
  • @pinug `var doneTypingInterval = 1000; //time in ms, 1 second for example` change this value to any what you want : ) – Tim007 Apr 18 '16 at 09:20
  • @Tim007 oh my god thank you so much sir thank you for your interest and thank you for your time sharing, that's what im looking for sir thank you i appreciate :))) – pinug Apr 18 '16 at 09:23
  • @Tim007 a bonus question sir how can we modify to its first string i mean after 1 second if user continues typing it returns back to the first string...ex **"kinin"** i wait 1 second and it becomes **"kiNG"** ..but when if user continues to type after 1 second from **"kinin"** to **"kinindan"** how can we change it to **"kinindan"** form – pinug Apr 18 '16 at 09:33
  • @pinug check update, i added code to change `kiNG` to `kinin` if continue typing after 1 second. – Tim007 Apr 18 '16 at 09:43
  • @Tim007 sir you are perfect THANK YOU SO MUCH :) – pinug Apr 18 '16 at 09:50
  • @Tim007 sir i want to add same case for **"nun"** ,**"in"** i tried several times to add these in plus but it didn't work, it is working only for **"nin"**, how can i add ? – pinug Apr 18 '16 at 13:06
  • `var re = /(\w)(nin|nun|in)([^a-zA-Z])/g; ` something like this – Tim007 Apr 18 '16 at 13:23
  • @yes for ex same case for **"kungunun"** but it has to change with **"ng"** => (**"kungung"**),,,or **"anganan"** with **"G"** => (**"angaG"**) ... – pinug Apr 18 '16 at 13:28
  • `var re = /(\w)(nan)([^a-zA-Z])/g; var subst = '$1G$3'; text2 = text2.replace(re, subst);` edit & repeat these line for other cases. – Tim007 Apr 18 '16 at 13:33
  • @Tim007 i did it sir, but i also changed the variable names maybe i shouldn't :/ – pinug Apr 18 '16 at 13:40
  • @Tim007 i don't know where am i making mistakes, can you send me a jsfiddle example again to see it sir ? – pinug Apr 18 '16 at 13:44
  • @Tim007 sir i got it but it is not working for **"nün"** :/ – pinug Apr 18 '16 at 15:05