I know the heading of this questions seems vague - but it's because I simply don't know how to summarize it appropriately.
我知道这个问题的标题似乎很模糊——但这是因为我根本不知道如何恰当地总结它。
I'm working on a project where I enter some text, and it's translated into something else.
我正在做一个项目,我输入一些文本,它被翻译成其他的东西。
There's a fiddle here.
这里有一个小提琴。
If I enter 4, it translates to the word for.
如果我输入4,它会翻译成for这个词。
If I enter b4, it should translate to before.
如果我输入b4,它应该转换到之前。
Instead, it translates to bfor, because it's capturing the variable 4 as a separate variable.
相反,它转换为bfor,因为它将变量4作为一个单独的变量。
I've tried changing the order, but it doesn't work. Is this a regex problem?
我试过改变顺序,但行不通。这是regex问题吗?
My variables are identified in the JS.
我的变量在JS中被标识。
var replaceValues = {
'4' : 'for',
'b4' : 'before'
}
$('.bs-text').keyup(function (event) {
newText = event.target.value;
for (var txt in replaceValues) {
var temp = new RegExp(txt, 'gim');
newText = newText.replace(temp, replaceValues[txt]);
}
$('.human-text').text(newText);
});
3 个解决方案
#1
1
As I noted in the comments, JS objects does not have defined order of its keys, so it is not a good idea to count on this when you know the dictionary will get much bigger.
正如我在注释中指出的,JS对象没有定义其键的顺序,所以当您知道字典将变得更大时,指望它不是一个好主意。
More about this in another SO question: Does JavaScript Guarantee Object Property Order?
关于这一点,在另一个SO问题:JavaScript是否保证对象属性的顺序?
Instead, use simple array that will have the order you define. Sorting of this dictionary array can be done in JS too, you do not need to handle this by your own.
相反,使用简单的数组,它将具有您定义的顺序。这个字典数组的排序也可以在JS中完成,您不需要自己处理它。
var replaceValues = [
{key: '4', value: 'for'},
{key: 'b4', value: 'before'},
];
// sort the values so longer keys go first
replaceValues.sort((a, b) => b.key.length - a.key.length);
$('.bs-text').keyup(function (event) {
var newText = event.target.value;
for (var txt in replaceValues) {
var replacement = replaceValues[txt];
var temp = new RegExp(replacement.key, 'gim');
newText = newText.replace(temp, replacement.value);
}
$('.human-text').text(newText);
});
You could also use ES6 Map
, it should have order guarantied. But be aware that it is not enough to create Map
from Object
:
你也可以使用ES6地图,它应该有订单守护。但请注意,仅从对象创建映射是不够的:
A Map object iterates its elements in insertion order — a for...of loop returns an array of [key, value] for each iteration.
Map对象以插入顺序迭代它的元素——A代表…对于每个迭代返回一个[key, value]数组。
It should be noted that a Map which is a map of an object, especially a dictionary of dictionaries, will only map to the object's insertion order—which is random and not ordered.
应该指出的是,地图是一个对象的地图,特别是字典的字典,它只会映射到对象的插入顺序——这是随机的,而不是有序的。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map Objects_and_maps_compared
#2
1
As mentioned in the comments, you have to look for the longest match first. One option is to generate a single regular expression from the search words, ordered by length, and use a callback to get the correct replacement value.
正如评论中提到的,您必须首先查找最长的匹配。一种方法是从搜索词中生成一个正则表达式(按长度排序),并使用回调获取正确的替换值。
var replaceValues = {
'4': 'for',
'b4': 'before'
};
// generates something equivalent to `/b4|4/gmi`
var pattern = new RegExp(
Object.keys(replaceValues)
.sort((a, b) => b.length - a.length)
.join('|'),
'gmi'
);
var newText = '4 me b4 me';
console.log(newText.replace(pattern, match => replaceValues[match]));
This works because the regex engine matches alternatives from left to right (i.e. if b4
matches it won't try to match 4
). Not sure how this solution scales with more searchwords, but it might actually better because you are only matching the string once instead of n
times, i.e. the regex engine doesn't have to traverse the whole string multiple times.
这工作,因为正则引擎匹配选择从左到右(即如果b4匹配它不会尝试匹配4)。不知道这个解决方案尺度searchwords,但它可能会更好,因为你只匹配字符串一旦代替n次,即正则引擎不必多次遍历整个字符串。
#3
0
The object property has ":"
character within property value
对象属性在属性值中具有“:”字符
$('.bs-text').keyup(function (event) {
var newText = event.target.value;
if (replaceValues[newText]) {
$('.human-text').text(replaceValues[newText])
};
});
jsfiddle http://jsfiddle.net/je89deam/5/
jsfiddle http://jsfiddle.net/je89deam/5/
#1
1
As I noted in the comments, JS objects does not have defined order of its keys, so it is not a good idea to count on this when you know the dictionary will get much bigger.
正如我在注释中指出的,JS对象没有定义其键的顺序,所以当您知道字典将变得更大时,指望它不是一个好主意。
More about this in another SO question: Does JavaScript Guarantee Object Property Order?
关于这一点,在另一个SO问题:JavaScript是否保证对象属性的顺序?
Instead, use simple array that will have the order you define. Sorting of this dictionary array can be done in JS too, you do not need to handle this by your own.
相反,使用简单的数组,它将具有您定义的顺序。这个字典数组的排序也可以在JS中完成,您不需要自己处理它。
var replaceValues = [
{key: '4', value: 'for'},
{key: 'b4', value: 'before'},
];
// sort the values so longer keys go first
replaceValues.sort((a, b) => b.key.length - a.key.length);
$('.bs-text').keyup(function (event) {
var newText = event.target.value;
for (var txt in replaceValues) {
var replacement = replaceValues[txt];
var temp = new RegExp(replacement.key, 'gim');
newText = newText.replace(temp, replacement.value);
}
$('.human-text').text(newText);
});
You could also use ES6 Map
, it should have order guarantied. But be aware that it is not enough to create Map
from Object
:
你也可以使用ES6地图,它应该有订单守护。但请注意,仅从对象创建映射是不够的:
A Map object iterates its elements in insertion order — a for...of loop returns an array of [key, value] for each iteration.
Map对象以插入顺序迭代它的元素——A代表…对于每个迭代返回一个[key, value]数组。
It should be noted that a Map which is a map of an object, especially a dictionary of dictionaries, will only map to the object's insertion order—which is random and not ordered.
应该指出的是,地图是一个对象的地图,特别是字典的字典,它只会映射到对象的插入顺序——这是随机的,而不是有序的。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map Objects_and_maps_compared
#2
1
As mentioned in the comments, you have to look for the longest match first. One option is to generate a single regular expression from the search words, ordered by length, and use a callback to get the correct replacement value.
正如评论中提到的,您必须首先查找最长的匹配。一种方法是从搜索词中生成一个正则表达式(按长度排序),并使用回调获取正确的替换值。
var replaceValues = {
'4': 'for',
'b4': 'before'
};
// generates something equivalent to `/b4|4/gmi`
var pattern = new RegExp(
Object.keys(replaceValues)
.sort((a, b) => b.length - a.length)
.join('|'),
'gmi'
);
var newText = '4 me b4 me';
console.log(newText.replace(pattern, match => replaceValues[match]));
This works because the regex engine matches alternatives from left to right (i.e. if b4
matches it won't try to match 4
). Not sure how this solution scales with more searchwords, but it might actually better because you are only matching the string once instead of n
times, i.e. the regex engine doesn't have to traverse the whole string multiple times.
这工作,因为正则引擎匹配选择从左到右(即如果b4匹配它不会尝试匹配4)。不知道这个解决方案尺度searchwords,但它可能会更好,因为你只匹配字符串一旦代替n次,即正则引擎不必多次遍历整个字符串。
#3
0
The object property has ":"
character within property value
对象属性在属性值中具有“:”字符
$('.bs-text').keyup(function (event) {
var newText = event.target.value;
if (replaceValues[newText]) {
$('.human-text').text(replaceValues[newText])
};
});
jsfiddle http://jsfiddle.net/je89deam/5/
jsfiddle http://jsfiddle.net/je89deam/5/