我希望能够检测到有人在自由文本输入字段中键入的单位。例如,如果他们键入100 kg
,我想检测出它是weight
。如果他们输入100 liter
,它将检测到volume
,依此类推。我希望它适用于不同风格的输入。例如,100kg
和100 kg
应该都被检测为体重。
这是我目前构建它的方式。它适用于简单的示例,但存在一些问题:
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
}
如果我输入randomliter
,它将因为字符串liter
而将其检测为音量。我该如何解决,以便它只检查完全匹配,同时仍然能够接受多种输入样式,例如
100kg
100 kg
kg 100
并全部检测为体重? 这是我可以使用正则表达式的东西吗?关键是他们可以自由输入值和单位,我需要检测值和单位。
答案 0 :(得分:3)
使用match
而不是includes
的正则表达式。
以下应针对kg示例执行以下操作。
regex = '^[0-9]*\s*kg\s*[0-9]*$'
cleanedString.match(regex)
有关正则表达式的演示/说明,请参见here。
答案 1 :(得分:2)
编辑:Mad的答案更好。如果您只是将“ randomLiter”与“ liter”进行比较,那么我的回答会更好,但您将“ 100 randomLiters”与“ liter”进行了比较,使Mad使用RegEx的方法更加适用。为了后代,我将在下面留下答案。
不是检查unit
数组中是否存在每个项目,而是反过来检查cleanedString
数组中是否存在cleanedString
:
也就是说,代替这个:
unit
...执行此操作:
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;
}
}
}
}
说明:
for (let unit in units) {
if(units[unit].includes(cleanedString)){
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
中的值之一完全匹配。
array
答案 2 :(得分:0)
以下函数将返回确切的类型:
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)))
此函数遍历数组中的每个单元类型,然后遍历每个不同的字符串(如果匹配),它将返回整个对象。
工作示例:
function getUnit(inputValue){
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"]
}
const result = Object.entries(units).find(([name, typos]) => typos.some(typo => inputValue.includes(typo)))
return result ? result[0] : null
}
console.log(getUnit('450 kg'))
console.log(getUnit('4 l'))
console.log(getUnit('50 meter/s'))
console.log(getUnit('850 rfeh'))
console.log(getUnit('4.56 kgram'))
console.log(getUnit('756 liter'))
console.log(getUnit('758 meter/sekund'))
答案 3 :(得分:-1)
尝试一下:
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";
}
}