11import defaultOptions , { Options } from './options'
2- import { Input , cloneDeep } from './core'
2+ import { Input , cloneDeep , MINUS } from './core'
33
44export interface Config {
55 prefix : string
@@ -34,7 +34,12 @@ export default class NumberFormat {
3434 number : Input
3535 isClean : boolean
3636 isCustomDecimal : boolean
37- preSurRegExp : RegExp
37+ noPreSuffix : boolean
38+ hasPreOrSuffix : boolean
39+ prefix : string
40+ preSufRegExp ?: RegExp
41+ prefixRegExp ?: RegExp
42+ suffixRegExp ?: RegExp
3843 numberRegExp : RegExp
3944 cleanRegExp : RegExp
4045 negativeRegExp : RegExp
@@ -47,14 +52,28 @@ export default class NumberFormat {
4752 this . number = ''
4853 this . isClean = ! reverseFill
4954
50- const escapedPrefix = prefix . replace ( / [ - / \\ ^ $ * + ? . ( ) | [ \] { } ] / g, '\\$&' )
51- const escapedSuffix = suffix . replace ( / [ - / \\ ^ $ * + ? . ( ) | [ \] { } ] / g, '\\$&' )
55+ // Use Negative Medium Space Unicode as default prefix if none provided
56+ const safePrefix = prefix
57+ const safeSuffix = suffix
58+
59+ const escapedPrefix = safePrefix . replace ( / [ - / \\ ^ $ * + ? . ( ) | [ \] { } ] / g, '\\$&' )
60+ const escapedSuffix = safeSuffix . replace ( / [ - / \\ ^ $ * + ? . ( ) | [ \] { } ] / g, '\\$&' )
61+
62+ if ( escapedPrefix ) {
63+ this . prefixRegExp = new RegExp ( `^${ escapedPrefix } ` )
64+ }
65+
66+ if ( escapedSuffix ) {
67+ this . suffixRegExp = new RegExp ( `${ escapedSuffix } $` )
68+ }
5269
53- this . preSurRegExp = new RegExp ( ` ${ escapedPrefix } | ${ escapedSuffix } ` , 'g' )
70+ this . prefix = prefix
5471 this . numberRegExp = new RegExp ( `[^0-9\\${ decimal } ]+` , 'gi' )
5572 this . cleanRegExp = new RegExp ( '[^0-9]+' , 'gi' )
5673 this . negativeRegExp = new RegExp ( '[^0-9\\-]+' , 'gi' )
5774 this . isCustomDecimal = decimal !== '.'
75+ this . noPreSuffix = ! safePrefix && ! safeSuffix
76+ this . hasPreOrSuffix = ! this . noPreSuffix
5877 }
5978
6079 isNull ( ) {
@@ -70,11 +89,11 @@ export default class NumberFormat {
7089 if ( this . input === null || this . input === undefined ) {
7190 return ''
7291 }
73- const hasMinus = this . input . toString ( ) . indexOf ( '-' ) >= 0
92+ const hasMinus = this . input . toString ( ) . indexOf ( MINUS ) >= 0
7493 if ( this . isClean ) {
75- return hasMinus && this . realNumber ( ) > 0 ? '-' : ''
94+ return hasMinus && this . realNumber ( ) > 0 ? MINUS : ''
7695 }
77- return hasMinus ? '-' : ''
96+ return hasMinus ? MINUS : ''
7897 }
7998
8099 toFixed ( ) {
@@ -88,29 +107,65 @@ export default class NumberFormat {
88107 }
89108
90109 numberOnly ( regExp ?: RegExp ) {
91- return this . input
92- ?. toString ( )
93- . replace ( this . preSurRegExp , '' )
94- . replace ( regExp || this . numberRegExp , '' )
110+ let number = this . input ?. toString ( )
111+
112+ if ( this . prefixRegExp ) {
113+ number = number . replace ( this . prefixRegExp , '' )
114+ }
115+
116+ if ( this . suffixRegExp ) {
117+ number = number . replace ( this . suffixRegExp , '' )
118+ }
119+
120+ return number . replace ( regExp || this . numberRegExp , '' )
121+ }
122+
123+ inputWithPreOrSuffix ( ) {
124+ if ( this . input && this . prefixRegExp ) {
125+ return this . prefixRegExp . test ( this . input . toString ( ) )
126+ }
127+
128+ if ( this . input && this . suffixRegExp ) {
129+ return this . suffixRegExp . test ( this . input . toString ( ) )
130+ }
131+
132+ return true
95133 }
96134
97135 isNegative ( ) {
98- return this . sign ( ) === '-'
136+ return this . sign ( ) === MINUS
137+ }
138+
139+ isNumber ( val ?: any ) {
140+ return ! isNaN ( this . toNumber ( val || this . input ) )
99141 }
100142
101143 numbers ( ) {
102- const { reverseFill, decimal } = this . options
103- const hasDeciaml = this . input . toString ( ) . indexOf ( decimal ) >= 0
104- const input = ! hasDeciaml && this . isCustomDecimal ? this . input + decimal : this . input
144+ const { reverseFill, decimal, separator } = this . options
105145
106146 if ( reverseFill ) {
107147 this . number = this . toFixed ( ) . replace ( '.' , decimal )
108- } else if ( typeof this . input === 'number' ) {
109- this . number = this . parts ( this . input . toString ( ) . replace ( '-' , '' ) , '.' ) . join ( decimal )
110- } else if ( ! isNaN ( this . toNumber ( input ) ) ) {
111- this . number = this . parts ( this . input . replace ( '-' , '' ) , '.' ) . join ( decimal )
112148 } else {
113- this . number = this . parts ( this . numberOnly ( ) ) . join ( decimal )
149+ const number = this . input
150+ ?. toString ( )
151+ . replace ( this . prefixRegExp ?? '' , '' )
152+ . replace ( this . suffixRegExp ?? '' , '' )
153+ . replace ( new RegExp ( MINUS , 'g' ) , '' )
154+
155+ const hasCustomDecimal = this . input . toString ( ) . indexOf ( decimal ) >= 0 && this . isCustomDecimal
156+ const realNumber = number . replace ( new RegExp ( `\\${ separator } ` , 'g' ) , '' ) . replace ( decimal , '.' )
157+
158+ if ( typeof this . input === 'number' ) {
159+ this . number = this . parts ( number , '.' ) . join ( decimal )
160+ } else if ( this . isNumber ( ) && ! hasCustomDecimal && ! this . inputWithPreOrSuffix ( ) && this . hasPreOrSuffix ) {
161+ // Only process separator-to-decimal conversion when necessary
162+ this . number = this . parts ( number , '.' ) . join ( decimal )
163+ } else if ( this . isNumber ( realNumber ) && ! hasCustomDecimal && this . inputWithPreOrSuffix ( ) && this . hasPreOrSuffix ) {
164+ this . number = this . parts ( realNumber , '.' ) . join ( decimal )
165+ } else {
166+ // If no custom decimal is detected, do not convert the separator
167+ this . number = this . parts ( this . numberOnly ( ) ) . join ( decimal )
168+ }
114169 }
115170
116171 return this . number
0 commit comments