Javascript 如何检测某人在输入字段中键入的单位
我希望能够检测到有人在自由文本输入字段中键入的单位。例如,如果他们输入Javascript 如何检测某人在输入字段中键入的单位,javascript,reactjs,Javascript,Reactjs,我希望能够检测到有人在自由文本输入字段中键入的单位。例如,如果他们输入100kg,我想检测它的重量。如果输入100升,则应检测体积,依此类推。我希望它能用于不同风格的输入。例如,100kg和100kg都应检测为重量 这就是我目前构建它的方式。它适用于简单的示例,但存在一些问题: import React from 'react'; import { render } from 'react-dom'; import PropTypes from 'prop-types'; import { ob
100kg
,我想检测它的重量。如果输入100升
,则应检测体积
,依此类推。我希望它能用于不同风格的输入。例如,100kg
和100kg
都应检测为重量
这就是我目前构建它的方式。它适用于简单的示例,但存在一些问题:
import React from 'react';
import { render } from 'react-dom';
import PropTypes from 'prop-types';
import { observer } from "mobx-react";
@observer
export default class DemoComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
inputValue: "",
unit: "no unit detected",
}
}
updateInputValue(e) {
let unit = this.detectUnit(e.target.value);
if(unit) {
this.setState({unit: unit,inputValue: e.target.value});
} else {
this.setState({unit: "no unit detected",inputValue:
e.target.value})
}
}
detectUnit(string) {
let currentUnit = false;
let cleanedString = string.toLowerCase();
for (let unit in units) {
if (units.hasOwnProperty(unit)) {
// do stuff
for(let i = 0; i < units[unit].length ; i++) {
if(cleanedString.includes(units[unit][i])) {
currentUnit = unit;
break;
}
}
}
}
console.log(currentUnit)
return currentUnit;
}
render() {
return (
<div id="testID">
<h1 className="democss">{this.props.title}</h1>
<div className="container">
<input value={this.state.inputValue} onChange={(e) =>
this.updateInputValue(e)} />
<h2 className="unit">{this.state.unit}</h2>
</div>
</div>
);
}
}
const units = {
velocity: ["m/s","km/h","meter/s","m/sekund", "meter/sekund",],
weight: ["kg","kilogram","kilo gram","kgram","k gram","kilo","k"],
volume: ["liter",], //add "l" later
}
从“React”导入React;
从'react dom'导入{render};
从“道具类型”导入道具类型;
从“mobx react”导入{observer};
@观察者
导出默认类DemoComponent扩展React.Component{
建造师(道具){
超级(道具);
此.state={
输入值:“”,
单位:“未检测到单位”,
}
}
更新输入值(e){
设单位=this.detectUnit(即目标值);
若有(单位){
this.setState({unit:unit,inputValue:e.target.value});
}否则{
this.setState({unit:“未检测到单元”),inputValue:
e、 target.value})
}
}
检测器(字符串){
设currentUnit=false;
让cleanedString=string.toLowerCase();
for(以单位表示){
if(单位hasOwnProperty(单位)){
//做事
对于(设i=0;i
{this.state.unit}
);
}
}
常数单位={
速度:[“米/秒”、“公里/小时”、“米/秒”、“米/秒”、“米/秒”、“米/秒”,
重量:[“千克”、“千克”、“千克”、“千克”、“千克”、“千克”、“克”、“克”、“千克”、“克”],
体积:[“升”,“升],//稍后添加“l”
}
如果我输入randomlile
,它会将其检测为音量,因为字符串little
存在。我如何修复它,使它只检查精确匹配,同时仍然能够接受多种输入样式,如
100公斤
100公斤
100公斤
并将它们全部检测为重量?
这是我可以用正则表达式的东西吗?关键是他们可以自由输入值和单位,我需要检测值和单位
编辑:Mad的答案更好。如果您只是简单地将“随机升”与“升”进行比较,我下面的答案会更好,但您将“100随机升”与“升”进行比较,这使得Mad使用正则表达式的方法更适用。我将把下面的答案留给子孙后代
不要检查单元
数组中的每个项目是否存在于清洁字符串
中,而是用另一种方法检查清洁字符串
是否存在于单元
数组中:
也就是说,与此相反:
for (let unit in units) {
if (units.hasOwnProperty(unit)) {
// do stuff
for(let i = 0; i < units[unit].length ; i++) {
if(cleanedString.includes(units[unit][i])) {
currentUnit = unit;
break;
}
}
}
}
说明:
units[unit]
是字符串数组
units[unit][i]
是一个字符串
cleanedString
是一个字符串
{stringA}.includes({stringB})
检查stringB
是否是stringA
cleanedString.includes(units[unit][i]))
// ...is the same as
'randomliter'.includes('liter')
// ...which will return 'true'
{array}.includes({stringB})
检查stringB
是否与数组中的一个值完全匹配
units[unit].includes(cleanedString)
// ...is the same as
['liter'].includes('randomliter')
// ...which will return 'false'.
对正则表达式使用match
,而不是includes
以下内容应该与您想要的kg示例相关
regex = '^[0-9]*\s*kg\s*[0-9]*$'
cleanedString.match(regex)
有关正则表达式的演示/解释,请参阅。尝试以下方法:
function detectUnit(string) {
const unit = string.replace(/\d+/g,'').trim().toLowerCase();
switch(true) {
case units.velocity.includes(unit):
return "velocity";
case units.weight.includes(unit):
return "weight";
case units.volume.includes(unit):
return "volume";
default:
return "default";
}
}
以下函数将返回确切的类型:
const units = {
velocity: ["m/s", "km/h", "meter/s", "m/sekund", "meter/sekund",],
weight: ["kg", "kilogram", "kilo gram", "kgram", "k gram", "kilo", "k"],
volume: ["liter", "l"]
}
Object.entries(units).find(([name, typos]) => typos.some(typo => inputValue.includes(typo)))
此函数迭代数组中的每个单元类型,然后遍历每个不同的字符串,如果其中一个匹配,则返回整个对象
工作示例:
函数getUnit(inputValue){
常数单位={
速度:[“米/秒”、“公里/小时”、“米/秒”、“米/秒”、“米/秒”、“米/秒”,
重量:[“千克”、“千克”、“千克”、“千克”、“千克”、“千克”、“克”、“克”、“千克”、“克”],
体积:[“升”,“升”]
}
const result=Object.entries(units.find)([name,typos])=>typos.some(typo=>inputValue.includes(typo)))
返回结果?结果[0]:空
}
控制台日志(getUnit('450 kg'))
console.log(getUnit('4l'))
控制台日志(getUnit('50米/秒'))
console.log(getUnit('850 rfeh'))
日志(getUnit('4.56 kgram'))
控制台日志(getUnit('756升'))
log(getUnit('758米/sekund'))
您正在使用的includes()
。您可能应该精确匹配字符串。或者做一个单词匹配。如果您正在使用for..in
,则不需要if(units.hasOwnProperty(unit))
。您可以假设单元
在迭代中确实显示了每个属性。这不是很枯燥。您应该使用某种迭代,而不是为每种单元类型硬编码一个案例。
const units = {
velocity: ["m/s", "km/h", "meter/s", "m/sekund", "meter/sekund",],
weight: ["kg", "kilogram", "kilo gram", "kgram", "k gram", "kilo", "k"],
volume: ["liter", "l"]
}
Object.entries(units).find(([name, typos]) => typos.some(typo => inputValue.includes(typo)))