mirror of https://github.com/abpframework/abp.git
6 changed files with 28 additions and 208 deletions
@ -1,156 +0,0 @@ |
|||||
class ExtractionResult { |
|
||||
public isMatch: boolean; |
|
||||
public matches: any[]; |
|
||||
|
|
||||
constructor(isMatch: boolean) { |
|
||||
this.isMatch = isMatch; |
|
||||
this.matches = []; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
enum FormatStringTokenType { |
|
||||
ConstantText, |
|
||||
DynamicValue, |
|
||||
} |
|
||||
|
|
||||
class FormatStringToken { |
|
||||
public text: string; |
|
||||
public type: FormatStringTokenType; |
|
||||
|
|
||||
constructor(text: string, type: FormatStringTokenType) { |
|
||||
this.text = text; |
|
||||
this.type = type; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
class FormatStringTokenizer { |
|
||||
tokenize(format: string, includeBracketsForDynamicValues: boolean = false): FormatStringToken[] { |
|
||||
const tokens: FormatStringToken[] = []; |
|
||||
|
|
||||
let currentText = ''; |
|
||||
let inDynamicValue = false; |
|
||||
|
|
||||
for (let i = 0; i < format.length; i++) { |
|
||||
const c = format[i]; |
|
||||
switch (c) { |
|
||||
case '{': |
|
||||
if (inDynamicValue) { |
|
||||
throw new Error( |
|
||||
'Incorrect syntax at char ' + |
|
||||
i + |
|
||||
'! format string can not contain nested dynamic value expression!', |
|
||||
); |
|
||||
} |
|
||||
|
|
||||
inDynamicValue = true; |
|
||||
|
|
||||
if (currentText.length > 0) { |
|
||||
tokens.push(new FormatStringToken(currentText, FormatStringTokenType.ConstantText)); |
|
||||
currentText = ''; |
|
||||
} |
|
||||
|
|
||||
break; |
|
||||
case '}': |
|
||||
if (!inDynamicValue) { |
|
||||
throw new Error( |
|
||||
'Incorrect syntax at char ' + |
|
||||
i + |
|
||||
'! These is no opening brackets for the closing bracket }.', |
|
||||
); |
|
||||
} |
|
||||
|
|
||||
inDynamicValue = false; |
|
||||
|
|
||||
if (currentText.length <= 0) { |
|
||||
throw new Error( |
|
||||
'Incorrect syntax at char ' + i + '! Brackets does not containt any chars.', |
|
||||
); |
|
||||
} |
|
||||
|
|
||||
let dynamicValue = currentText; |
|
||||
if (includeBracketsForDynamicValues) { |
|
||||
dynamicValue = '{' + dynamicValue + '}'; |
|
||||
} |
|
||||
|
|
||||
tokens.push(new FormatStringToken(dynamicValue, FormatStringTokenType.DynamicValue)); |
|
||||
currentText = ''; |
|
||||
|
|
||||
break; |
|
||||
default: |
|
||||
currentText += c; |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
if (inDynamicValue) { |
|
||||
throw new Error('There is no closing } char for an opened { char.'); |
|
||||
} |
|
||||
|
|
||||
if (currentText.length > 0) { |
|
||||
tokens.push(new FormatStringToken(currentText, FormatStringTokenType.ConstantText)); |
|
||||
} |
|
||||
|
|
||||
return tokens; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
export class FormattedStringValueExtractor { |
|
||||
extract(str: string, format: string): ExtractionResult { |
|
||||
if (str === format) { |
|
||||
return new ExtractionResult(true); |
|
||||
} |
|
||||
|
|
||||
const formatTokens = new FormatStringTokenizer().tokenize(format); |
|
||||
if (!formatTokens) { |
|
||||
return new ExtractionResult(str === ''); |
|
||||
} |
|
||||
|
|
||||
const result = new ExtractionResult(true); |
|
||||
|
|
||||
for (let i = 0; i < formatTokens.length; i++) { |
|
||||
const currentToken = formatTokens[i]; |
|
||||
const previousToken = i > 0 ? formatTokens[i - 1] : null; |
|
||||
|
|
||||
if (currentToken.type === FormatStringTokenType.ConstantText) { |
|
||||
if (i === 0) { |
|
||||
if (str.indexOf(currentToken.text) !== 0) { |
|
||||
result.isMatch = false; |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
str = str.substr(currentToken.text.length, str.length - currentToken.text.length); |
|
||||
} else { |
|
||||
const matchIndex = str.indexOf(currentToken.text); |
|
||||
if (matchIndex < 0) { |
|
||||
result.isMatch = false; |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
result.matches.push({ name: previousToken.text, value: str.substr(0, matchIndex) }); |
|
||||
str = str.substring(0, matchIndex + currentToken.text.length); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
const lastToken = formatTokens[formatTokens.length - 1]; |
|
||||
if (lastToken.type === FormatStringTokenType.DynamicValue) { |
|
||||
result.matches.push({ name: lastToken.text, value: str }); |
|
||||
} |
|
||||
|
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
isMatch(str: string, format: string): string[] { |
|
||||
const result = new FormattedStringValueExtractor().extract(str, format); |
|
||||
if (!result.isMatch) { |
|
||||
return []; |
|
||||
} |
|
||||
|
|
||||
const values = []; |
|
||||
for (let i = 0; i < result.matches.length; i++) { |
|
||||
values.push(result.matches[i].value); |
|
||||
} |
|
||||
|
|
||||
return values; |
|
||||
} |
|
||||
} |
|
||||
Loading…
Reference in new issue