I've been trying to figure out how to convert visual hebrew to logical hebrew with vanilla JavaScript by just making a function that reverses the string given to it and then just replacing the brackets with the correct ones
e.g. ( to ) or ) to (.
Here is an explanation for whats the difference between the two:
https://www.w3.org/International/questions/qa-visual-vs-logical
When you reverse a string, the brackets stay the same, so for example when you have :) שלום the reversed string will be םולש :( and thats why i added the switch case
Whats going wrong is Hebrew combined with English, im using this function to print hebrew correctly in minecraft education (what it does is - it prints hebrew flipped so that the string starts from the end and ends at the start) and as you can see in the image in this link - https://imgur.com/a/zEwHCmA , the first line is supposed to be the correct one, but the second one is the one being printed
Is there a chance it can be done with regex?
function myHebrewPrint(text: string ): void {
let reversed=""
for(let char of text)
{
switch(char)
{
case "(":
char = ")";
break;
case ")":
char = "(";
break;
case "[":
char = "]";
case "]":
char = "[";
break;
case "{":
char = "}";
break;
case "}":
char = "{";
break;
default:
break;
}
reversed=char+reversed
}
console.log(reversed)
}
Edit: I'm leaving this in case someone wants to have an attempt at this.
If I understood the requirements correctly, I think I managed to have this working. I have some explanation as comments.
function visualToLogicalHebrew(text) {
const hasHebrew = new RegExp("^[\u0590-\u05FF]+$"); //pattern to check if word has hebrew letters
const arr = text.split(' '); //split the whole text by space, having an array full of words
let sentence = "";
for (const word of arr) {
let isHebrew = hasHebrew.test(word);
if (isHebrew) {
sentence = word.split("").reverse().join("") + " " + sentence; //if hebrew then reverse all letters, add space and the previous sentence
}
else {
sentence = sentence + word + " ";
}
}
return sentence;
}
let result = visualToLogicalHebrew(":) שלום :subnetשלום");
console.log(result);
Attaches my solution based on #Costa solution and adaptation to the complex needs in my case
The first regex pattern matches the Hebrew / Arabic characters and the next character (except for a new line) and repeat to export entire verses
The function inside the replace convert the string to array and reverse it
The second regular expression test if the extra character taken is NOT an appropriate letter like a semicolon or anything else that should not be reversed and move it back to the end by shift and push
The join convert the array back to string
function reverseRTLchars(text){
//Hebrew U+0590 to U+05FF
//Arabic U+0600 to U+06FF
return text.replace(/([\u0590-\u06FF]+.)+/g, function(m){
m = m.split('').reverse();
if(/[^\u0590-\u06FF]/.test(m[0])){
m.push(m.shift())
}
return m.join('');
})
}
var string = `
םלוע םולש! םויה ריואה גזמ המ?
ש"פוסה דעו םויהמ: תיקלח ןנועמ דע ריהב
ב םוי' 28 ץרמ 2022 (ב"פשת)
`;
document.getElementById('conten').innerHTML = reverseRTLchars(string);
<pre id="conten" dir="rtl"></pre>
Related
So a string is entered, and then this is, while very poorly done, meant to check each char in the string and if the char is upper case it is meant to output that back into a new string that is the same as the old one with the word capital written after the letter. What it is doing is for every instance of the capital letter it is concating another capital onto the first instance. Each letter should end up with its own marker, but it is instead being bundled on one.
let str = 'I am In A Big Iron Arboretum.';
let nstr = str;
while (i \<= len) {
let char = str.charAt(i);
if (char == char.toLowerCase()) {
//console.log('oi');
} else {
if (char == char.toUpperCase()) {
let fchar = char + ' capital';
//console.log(fchar);
nstr = nstr.replace(char, fchar);
//console.log(nstr);
}
}
i++;
}
This is what I have tried doing, I at first thought it was just missing some but the console reads it all then I found that the instances after the first letter match the amount of times that letter appears. I am intending for the program to concat the word capital after the letters it finds are capitals. It doesn't matter that the base words are broken up.
I am doing a algorithm in freeCodeCamp.(https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/search-and-replace)
The task is as below:
Perform a search and replace on the sentence using the arguments provided and return the new sentence.
First argument is the sentence to perform the search and replace on.
Second argument is the word that you will be replacing (before).
Third argument is what you will be replacing the second argument with (after).
Note:
Preserve the case of the first character in the original word when you are replacing it. For example if you mean to replace the word "Book" with the word "dog", it should be replaced as "Dog"
**
myReplace("Let us get back to more Coding", "Coding", "algorithms") should return "Let us get back to more Algorithms".
myReplace("Let us go to the store", "store", "mall") should return "Let us go to the mall".
**
//if the before is uppercase, the after should be uppercase also
// str = str.replace(before, after);
var regex = /[A-Z]+/g; //check for uppercase
var newStr = "";
console.log(regex.test(before));
if (regex.test(before)) {
//if uppercase, return true, "after" convert to uppercase
after = after.toUpperCase();
newStr = after[0];
for (var i = 1; i < after.length; i++) {
//start at index=1 letter, all convert to
newStr += after[i].toLowerCase();
}
console.log(newStr);
str = str.replace(before, newStr);
} else {
str = str.replace(before, after);
}
// console.log(newStr);
console.log(str);
return str;
}
I think there should be OK for the code, but can anyone help find why the if statement can't work.
Much thanks!
The problem is that you're calling regex.test() multiple times on the same regular expression instance.
[...]
var regex = /[A-Z]+/g; //check for uppercase
var newStr = "";
console.log(regex.test(before));
if (regex.test(before)) {
//if uppercase, return true, "after" convert to uppercase
after = after.toUpperCase();
[...]
If your string is Hello_there, the first regex.test() will return true, because Hello matched. If you call regex.test() again with the same regex instance, it will have advanced in the string, and try to match starting with _there. In this case, it will fail, because _there does not begin with a capital letter between A and Z.
There are a lot of ways to fix this issue. Perhaps the simplest is to store the result of the first call to a variable, and use it everywhere you're calling regex.test():
[...]
var regex = /[A-Z]+/g; //check for uppercase
var newStr = "";
var upper_check = regex.test(before);
console.log(upper_check);
if (upper_check) {
[...]
It seems overkill to use a regex, when you really need to only check the first character. Your regex will find uppercase letters anywhere...
If the assignment is to only change one occurrence, then a regex is not really the right tool here: it does not really help to improve the code nor the efficiency. Just do:
function myReplace(str, before, after) {
if (before[0] === before[0].toUpperCase()) {
after = after[0].toUpperCase() + after.slice(1);
} else {
after = after[0].toLowerCase() + after.slice(1);
}
return str.replace(before, after);
}
function myReplace(str, before, after) {
var upperRegExp = /[A-Z]/g
var lowerRegExp = /[a-z]/g
var afterCapitalCase = after.replace(/^./, after[0].toUpperCase());
if (before[0].match(upperRegExp)) {
return str.replace(before, afterCapitalCase)
} else if (after[0].match(upperRegExp) && before[0].match(lowerRegExp)) {
return str.replace(before, after.toLowerCase());
} else {
return str.replace(before, after)
}
}
I have written below function to convert space with hyphen or reverse
space with hyphen str.trim().replace(/\s+/g, '-')
hyphen with space str.replace(/\-/g,' ')
But now I am trying to replace single hyphen with double hyphen, I can't use point 1 function because it convert single/multiple occurrence instead of single.
Is there any way to write regex which do 3 operation in single formula
convert forward slash with underscore replace(/\//g, '_')
convert space with single hyphen
convert single hyphen with multiple hyphen
e.g.
regex 1 change
"Name/Er-Gourav Mukhija" into "Name_Er--Gourav-Mukhija"
regex 2 do reverse of it.
You could use a callback function instead of a replace string. That way you can specify and replace all characters at once.
const input = 'Name/Er-Gourav Mukhija';
const translate = {
'/': '_',
'-': '--',
' ': '-',
};
const reverse = {
'_': '/',
'--': '-',
'-': ' ',
};
// This is just a helper function that takes
// the input string, the regex and the object
// to translate snippets.
function replaceWithObject( input, regex, translationObj ) {
return input.replace( regex, function( match ) {
return translationObj[ match ] ? translationObj[ match ] : match;
} );
}
function convertString( input ) {
// Search for /, - and spaces
return replaceWithObject( input, /(\/|\-|\s)/g, translate );
}
function reverseConvertedString( input ) {
// Search for _, -- and - (the order here is very important!)
return replaceWithObject( input, /(_|\-\-|\-)/g, reverse );
}
const result = convertString( input );
console.log( result );
console.log( reverseConvertedString( result ) );
It is not possible to write a Regex formula which does conditional replacements (ie a->b, c->d). I would instead try to create two statements to replace " " -> "--" and "/" -> "_".
You can use your existing code for both of these operations. I would recommend using this site for building and testing Regexes in the future.
Consider var str = "Name/Er-Gourav Mukhija"
To convert forward slash with underscore, as you mentioned use replace(/\//g, '_')
To convert space with single hyphen, use replace(/\s+/g, '-')
To convert single hyphen to double hyphen, use replace(/\-/g, '--').
All these 3 can be combined into:
str.replace(/\//g, '_').replace(/\s+/g, '-').replace(/\-/g, '--')
You should use a loop to do all at once:
str = str.split("");
var newStr = "";
str.forEach(function (curChar) {
switch(curChar) {
case " ":
newStr += "-";
break;
case "/":
newStr += "_";
break;
case "-":
newStr += "--";
break;
default:
newStr += curChar;
}
});
str = newStr;
Feel free to turn this into a function if you like. I also havven't made it do the reverse, but all you'd need to do is replace the assignment strings with the case strings in the switch () statement.
There's no way to do it all with regex, as your later regex will overwrite your first regex in at least one case no matter how you write it.
For making 1st letter of any word in Upper case, I am using below -
var HVal = "SchON";
HVal.toLowerCase().replace(/\b[a-z]/g,function(f){return f.toUpperCase();});
I get the correct output here as "Schon". However, this code does not work if my string contains umlaut vowel e.g. HVal = "SchÖN". the output here is "SchöN". How can I make this work for strings containing umlaut letters ?
The solution is
var HVal = "SchÖN dasdNdsad";
HVal.toLowerCase().replace(/(^[a-z])|(\s[a-z])/g,function(f){return f.toUpperCase();});
Use can something like this
var HVal = "SchÖN";
HVal=capitalize(HVal);
alert(HVal);
function capitalize(string) {
return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
}
I want to after type Title of post automatically take value and create slug. My code works fine with English Latin characters but problem is when I type characters 'čćšđž'. Code replace first type of this characters in string but if character is repeated than is a problem. So, for testing purpose this title 'šžđčćžđš čćšđžčćšđž čćšđžčć ćčšđžšžčćšđ ćčšžčć' is converted to this slug 'szdcc'.
This is my jquery code:
$('input[name=title]').on('blur', function() {
var slugElement = $('input[name=slug]');
if(slugElement.val()) {
return;
}
slugElement.val(this.value.toLowerCase().replace('ž', 'z').replace('č','c').replace('š', 's').replace('ć', 'c').replace('đ', 'd').replace(/[^a-z0-9-]+/g, '-').replace(/^-+|-+$/g, ''));
});
How to solve this problems? Also is it possible to this few characters put in same replace() function?
Try this:
function clearText(inp) {
var wrong = 'čćšđž';
var right = 'ccsdz';
var re = new RegExp('[' + wrong + ']', 'ig');
return inp.replace(re, function (m) { return right.charAt(wrong.indexOf(m)); });
}
replace() only replaces the first occurrence unless regex is used with global modifier. You will need to change them all to regular expression.
replace(/ž/g, "z")
As far as I know, it will not be possible to use a single replace() in your case.
If you are concerned with chaining a bunch of .replace() together, you might be better off writing some custom code to replace these characters.
var newStr = "";
for (var i = 0; i < str.length; i++) {
var c = str.charAt(i);
switch (c) {
case "ž": newStr += "z"; break;
default: newStr += c; break;
}
}