React Native TextInput 实现文本间隔

效果展示

这里写图片描述

在学习javaScript怎么使用正则表达式的时候,灵感突然来了 ,是否可以使用分组的方法来实现文本间隔。

效果是如图 (在空格处删,效果不好只是光标前移了,暂时优化不来)

思路
在输入文本时,利用onChangeText方法,拆分文本,使它们四个四个一起,然后拼接空格就可以。
实现

  1. 第一步 :输入中判断是否输入的是数字

     if (typeof str === 'string') {
          //替换空格或者非数字字符
          // /g是重头匹配到尾部
          return str.replace(/\s|\D+/g, '');
     }
  2. 切割文本

      //正则 分组  返回一个数组
      //如:输入 012345678910
      //得到 [012345678910,0123,4567,8910]
      //第一个元素是正则表达式匹配到的整个字符串,后面的字符串表示匹配成功的子串
      let reg = /^(\d{0,4})(\d{0,4})(\d{0,4})$/;
      let arr = reg.exec(str);

    代码部分

'use strict';
import React, {Component, PropTypes} from "react";

import {
    StyleSheet,//样式
    View,//视图组件;
    Image,//图片
    TextInput,//输入框
    TouchableOpacity,//一个类似button的组件
} from "react-native";

export default class TextInputSplitNum extends Component {

// 传递参数属性定义
    static PropTypes = {
        onButtonClick: PropTypes.func.isRequired
    }

    // 构造
    constructor(props) {
        super(props);
        // 初始状态
        this.state = {
            inputValue: "",
        };
        this.onChange = this._onChange.bind(this);
    }

    _isNull(str) {
        let result = true;
        if (str === "" || str === undefined) {
            result = true;
        }

        if (str.length > 0) {
            result = false;
        }
        return result;
    }

    _replaceSpace(str) {
        if (typeof str === 'string') {
            //替换空格或者非数字字符
            return str.replace(/\s|\D+/g, '');
        }
        return "";
    }

    _splitNum(str) {
        //这里我把它写死了  需要修改正则公式 需要自己进行定义正则
        if (str && 13 > str.length > 0) {
            //正则 分组  返回一个数组
            //如:输入 012345678910
            //得到 [012345678910,0123,4567,8910]
            //第一个元素是正则表达式匹配到的整个字符串,后面的字符串表示匹配成功的子串
            let reg = /^(\d{0,4})(\d{0,4})(\d{0,4})$/;
            let arr = reg.exec(str);
            let result = '';
            for (let i = 1; i < arr.length; i++) {
                if (arr[i]) {
                    if (i === 1) {
                        result = arr[1];
                    } else {
                        result = result + " " + arr[i];
                    }
                } else {
                    break;
                }
            }

            //这个写法的不好  但直观
            // if (arr[1]) {
            //     result = arr[1];
            //     if (arr[2]) {
            //         result = result + " " + arr[2];
            //         if (arr[3]) {
            //             result = result + " " + arr[3];
            //         }
            //     }
            // }
            return result;
        }
        return "";
    }


    render() {
        let {inputValue} = this.state;
        return (
            <View style={styles.container}>

                <TextInput
                    underlineColorAndroid="transparent"
                    numberOfLines={1}
                    clearButtonMode={'never'}
                    maxLength={14}
                    keyboardType={'numeric'}
                    value={inputValue}
                    onChangeText={this.onChange}
                    {...this.props}/>
                {this._isNull(inputValue) ? null : this._getRightButtonView()}
            </View>
        );
    }

    _getRightButtonView() {
        //右侧按钮图
        let source = require('../../img/input_close.png');
        return (
            <TouchableOpacity activeOpacity={0.5}
                              style={styles.closeOpacityStyle}
                              onPress={() => {
                                  this.props.onButtonClick();
                              }}>
                <Image style={styles.closeStyle}
                       source={source}/>
            </TouchableOpacity>)
    }

    clearInputValue() {
        this.setState({inputValue: ""})
    }

    getInputValue() {
        return this.state.inputValue;
    }

    _onChange(changeText) {
        let value = this._splitNum(this._replaceSpace(changeText))
        this.setState({
            inputValue: value,
        });
    }

}

const styles = StyleSheet.create(
    {
        container: {
            flex: 1,
            flexDirection: 'row',
            alignItems: 'center'
        },
        closeStyle: {
            height: 18,
            width: 18,
        },
        closeOpacityStyle: {
            height: 54,
            width: 54,
            justifyContent: 'center',
        },
    }
)

使用

 <View style={{
         backgroundColor: 'white',
         width: width,
         height: DP.dp45,
         marginTop: DP.dp20,
         flexDirection: 'row',
         alignItems: 'center'
     }}>
         <Text style={{
             marginLeft: DP.dp11,
             color: "#333333",
             fontSize: 17,
         }}>
             车号编号
         </Text>

         <TextInputSplitNum 
             numberOfLines={1}
             underlineColorAndroid="transparent"
             maxLength={50}
             style={{
                 fontSize: 16,
                 color: "#333333",
                 width: width - DP.dp11 * 3 - DP.dp40
             }}
             ref={(c) => this.split = c}
             onButtonClick={()=>{
                 //根据需要自己控制
                 this.split.clearInputValue();
             }}
             placeholder={"请输入您的车辆编号"}
             placeholderTextColor={"#999999"}/>
  </View>

补充资料

1. 通过new RegExp(‘正则表达式’)创建一个RegExp对象

var re2 = new RegExp('ABC\\-001');

2. 通过/正则表达式/写出

var re1 = /ABC\-001/;

RegExp对象的test()方法用于测试给定的字符串是否符合条件。

var re = /^\d{3}\-\d{3,8}$/;
re.test('010-12345'); // true
re.test('010-1234x'); // false
re.test('010 12345'); // false
let a = 'a,b;; c  d'.split(/[\s\,\;]+/)

console.log(a); // ['a', 'b', 'c', 'd']
console.log("a.length ="+a.length); //a.length =4
for(let num of a){
  console.log(num);//a b c d
}

分组

用()表示的就是要提取的分组(Group)
^(\d{3})-(\d{3,8})$分别定义了两个组

var re = /^(\d{3})-(\d{3,8})$/;
re.exec('010-12345'); // ['010-12345', '010', '12345']
re.exec('010 12345'); // null

exec()方法在匹配成功后,会返回一个Array,第一个元素是正则表达式匹配到的整个字符串,后面的字符串表示匹配成功的子串

exec()方法在匹配失败时返回null。

特殊的标志

JavaScript的正则表达式还有几个特殊的标志,最常用的是g,表示全局匹配:

全局匹配可以多次执行exec()方法来搜索一个匹配的字符串。
当我们指定g标志后,每次运行exec()
正则表达式本身会更新lastIndex属性,表示上次匹配到的最后索引:

var s = 'JavaScript, VBScript, JScript and ECMAScript';
var re=/[a-zA-Z]+Script/g;

// 使用全局匹配:
re.exec(s); // ['JavaScript']
re.lastIndex; // 10

re.exec(s); // ['VBScript']
re.lastIndex; // 20

re.exec(s); // ['JScript']
re.lastIndex; // 29

re.exec(s); // ['ECMAScript']
re.lastIndex; // 44

re.exec(s); // null,直到结束仍没有匹配到
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值