简体   繁体   English

提取Javascript中的JPA命名参数

[英]Extract JPA Named Parameters in Javascript

I am trying to extract JPA named parameters in Javasacript.我正在尝试在 Javasacript 中提取 JPA 命名参数。 And this is the algorithm that I can think of这是我能想到的算法

const notStrRegex = /(?<![\S"'])([^"'\s]+)(?![\S"'])/gm
const namedParamCharsRegex = /[a-zA-Z0-9_]/;

/**
 * @returns array of named parameters which,
 * 1. always begins with :
 * 2. the remaining characters is guranteed to be following {@link namedParamCharsRegex}
 *
 * @example
 * 1. "select * from a where id = :myId3;" -> [':myId3']
 * 2. "to_timestamp_tz(:FROM_DATE, 'YYYY-MM-DD\"T\"HH24:MI:SS')" -> [':FROM_DATE']
 * 3. "TO_CHAR(ep.CHANGEDT,'yyyy=mm-dd hh24:mi:ss')" -> []
 */
export function extractNamedParam(query: string): string[] {
  return (query.match(notStrRegex) ?? [])
    .filter((word) => word.includes(':'))
    .map((splittedWord) => splittedWord.substring(splittedWord.indexOf(':')))
    .filter((splittedWord) => splittedWord.length > 1) // ignore ":"
    .map((word) => {
      // i starts from 1 because word[0] is :
      for (let i = 1; i < word.length; i++) {
        const isAlphaNum = namedParamCharsRegex.test(word[i]);
        if (!isAlphaNum) return word.substring(0, i);
      }
      return word;
    });
}

I got inspired by the solution in https://stackoverflow.com/a/11324894/12924700 to filter out all characters that are enclosed in single/double quotes.我从https://stackoverflow.com/a/11324894/12924700中的解决方案得到启发,过滤掉所有包含在单引号/双引号中的字符。

While the code above fulfilled the 3 use cases above.虽然上面的代码满足了上面的 3 个用例。 But when a user input但是当用户输入

const testStr  = '"user input invalid string \' :shouldIgnoreThisNamedParam \' in a string"'
extractNamedParam(testStr) // should return [] but it returns [":shouldIgnoreThisNamedParam"] instead

I did visit the source code of hibernate to see how named parameters are extracted there, but I couldn't find the algorithm that is doing the work.我确实访问了 hibernate 的源代码,看看那里是如何提取命名参数的,但我找不到正在做这项工作的算法。 Please help.请帮忙。

You can use您可以使用

/"[^\\"]*(?:\\[\w\W][^\\"]*)*"|'[^\\']*(?:\\[\w\W][^\\']*)*'|(:\w+)/g

Get the Group 1 values only.仅获取第 1 组值。 See the regex demo .请参阅正则表达式演示 The regex matches strings between single/double quotes and captures : + one or more word chars in all other contexts.正则表达式匹配单引号/双引号之间的字符串并捕获: + 所有其他上下文中的一个或多个单词字符。

See the JavaScript demo:请参阅 JavaScript 演示:

 const re = /"[^\\"]*(?:\\[\w\W][^\\"]*)*"|'[^\\']*(?:\\[\w\W][^\\']*)*'|(:\w+)/g; const text = "to_timestamp_tz(:FROM_DATE, 'YYYY-MM-DD\"T\"HH24:MI:SS')"; let matches=[], m; while (m=re.exec(text)) { if (m[1]) { matches.push(m[1]); } } console.log(matches);

Details :详情

  • "[^\\"]*(?:\\[\w\W][^\\"]*)*" - a " , then zero or more chars other than " and \ ( [^"\\]* ), and then zero or more repetitions of any escaped char ( \\[\w\W] ) followed with zero or more chars other than " and \ , and then a " "[^\\"]*(?:\\[\w\W][^\\"]*)*" - 一个" ,然后是"\ ( [^"\\]*以外的零个或多个字符[^"\\]* ),然后是任何转义字符( \\[\w\W] )的零次或多次重复,后跟除"\之外的零次或更多字符,然后是"
  • | - or - 或者
  • '[^\\']*(?:\\[\w\W][^\\']*)*' - a ' , then zero or more chars other than ' and \ ( [^'\\]* ), and then zero or more repetitions of any escaped char ( \\[\w\W] ) followed with zero or more chars other than ' and \ , and then a ' '[^\\']*(?:\\[\w\W][^\\']*)*' - 一个' ,然后是'\ ( [^'\\]*以外的零个或多个字符[^'\\]* ),然后是任何转义字符 ( \\[\w\W] ) 的零次或多次重复,后跟除'\之外的零次或多次字符,然后是'
  • | - or - 或者
  • (:\w+) - Group 1 (this is the value we need to get, the rest is just used to consume some text where matches must be ignored): a colon and one or more word chars. (:\w+) - 第 1 组(这是我们需要获取的值,rest 仅用于处理必须忽略匹配的一些文本):一个冒号和一个或多个单词字符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM