首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用regexp提取glsl函数体

使用regexp提取glsl函数体
EN

Stack Overflow用户
提问于 2020-12-19 14:50:35
回答 2查看 75关注 0票数 2

我在使用javascript提取glsl脚本中的函数时遇到了问题。

下面是glsl的内容:

代码语言:javascript
复制
 precision highp float;                           
  varying vec4 v_color;                                 
  #if USE_TEXTURE                                       
      varying vec2 v_uv0;                               
      uniform sampler2D texture;                        
  #endif                                                
vec2 sfx_func_uv_to_01(vec4 ucrect, vec2 uv) {
    return vec2(
        sfx_func_uv_to_01(ucrect[0], ucrect[0] + ucrect[2], uv.x),
        1.0 - sfx_func_uv_to_01(ucrect[1], ucrect[1] - ucrect[3], uv.y)
    );
}
vec2 sfx_func_uv_to_01(vec4 ucrect, vec2 uv) {
    return vec2(1.0, 2.0);
}
vec4 sfx_fs_output_uv_quarter(vec2 uv, vec4 color) {
    vec4 result = color;
    return result;
}
 void main () {                                    
    vec2 uv = v_uv0;                                  
    vec4 color = texture2D(texture, uv);              
    gl_FragColor = color;
}                                             

我想用正文提取脚本中的4个函数。所以我尝试了reg:

代码语言:javascript
复制
/^(vec4|vec3|vec2|float|int).*\{.*\}/gms

而js代码是:

代码语言:javascript
复制
for (const match of glsl1.matchAll(/^(vec4|vec3|vec2|float|int).*\{.*\}/gms)) {
    console.log(match[0]);
}

我只得到一个结果,而不是4个函数:

代码语言:javascript
复制
vec2 sfx_func_uv_to_01(vec4 ucrect, vec2 uv) {
    return vec2(
        sfx_func_uv_to_01(ucrect[0], ucrect[0] + ucrect[2], uv.x),
        1.0 - sfx_func_uv_to_01(ucrect[1], ucrect[1] - ucrect[3], uv.y)
    );
}
vec2 sfx_func_uv_to_01(vec4 ucrect, vec2 uv) {
    return vec2(1.0, 2.0);
}
vec4 sfx_fs_output_uv_quarter(vec2 uv, vec4 color) {
    vec4 result = color;
    return result;
}
 void main () {                                    
    vec2 uv = v_uv0;                                  
    vec4 color = texture2D(texture, uv);              
    gl_FragColor = color;
}    

我为多行文本寻找非贪婪模式的解决方案,但徒劳无功。

任何建议都将不胜感激,谢谢:)

EN

回答 2

Stack Overflow用户

发布于 2020-12-20 07:34:51

使用

代码语言:javascript
复制
/^(\s*)(vec4|vec3|vec2|float|int|void).*?{[\s\S]*?^\1}\s*$/gm

参见proof

说明

代码语言:javascript
复制
--------------------------------------------------------------------------------
  ^                        the beginning of the string
--------------------------------------------------------------------------------
  (                        group and capture to \1:
--------------------------------------------------------------------------------
    \s*                      whitespace (\n, \r, \t, \f, and " ") (0
                             or more times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
  )                        end of \1
--------------------------------------------------------------------------------
  (                        group and capture to \2:
--------------------------------------------------------------------------------
    vec4                     'vec4'
--------------------------------------------------------------------------------
   |                        OR
--------------------------------------------------------------------------------
    vec3                     'vec3'
--------------------------------------------------------------------------------
   |                        OR
--------------------------------------------------------------------------------
    vec2                     'vec2'
--------------------------------------------------------------------------------
   |                        OR
--------------------------------------------------------------------------------
    float                    'float'
--------------------------------------------------------------------------------
   |                        OR
--------------------------------------------------------------------------------
    int                      'int'
--------------------------------------------------------------------------------
   |                        OR
--------------------------------------------------------------------------------
    void                     'void'
--------------------------------------------------------------------------------
  )                        end of \2
--------------------------------------------------------------------------------
  .*?                      any character except \n (0 or more times
                           (matching the least amount possible))
--------------------------------------------------------------------------------
  {                        '{'
--------------------------------------------------------------------------------
  [\s\S]*?                 any character of: whitespace (\n, \r, \t,
                           \f, and " "), non-whitespace (all but \n,
                           \r, \t, \f, and " ") (0 or more times
                           (matching the least amount possible))
--------------------------------------------------------------------------------
  ^                        the beginning of the string
--------------------------------------------------------------------------------
  \1                       what was matched by capture \1
--------------------------------------------------------------------------------
  }                        '}'
--------------------------------------------------------------------------------
  \s*                      whitespace (\n, \r, \t, \f, and " ") (0 or
                           more times (matching the most amount
                           possible))
--------------------------------------------------------------------------------
  $                        before an optional \n, and the end of the
                           string
票数 0
EN

Stack Overflow用户

发布于 2021-10-08 14:49:36

我不敢尝试使用正则表达式来跟踪花括号的无限嵌套,而是尝试使用g开关沿着函数头进行split() (这样就保留了分隔符),然后将头-体对连接起来。代码假设在第一个函数定义之前有一些前言,这对于大多数GLSL源来说可能是正确的,并且不期望在函数之间有任何东西(尽管code=code.substr(0,code.lastIndexOf("}")+1);可能可以解决这种情况)。

代码语言:javascript
复制
const source=`precision highp float;                           
  varying vec4 v_color;                                 
  #if USE_TEXTURE                                       
      varying vec2 v_uv0;                               
      uniform sampler2D texture;                        
  #endif                                                
vec2 sfx_func_uv_to_01(vec4 ucrect, vec2 uv) {
    return vec2(
        sfx_func_uv_to_01(ucrect[0], ucrect[0] + ucrect[2], uv.x),
        1.0 - sfx_func_uv_to_01(ucrect[1], ucrect[1] - ucrect[3], uv.y)
    );
}
vec2 sfx_func_uv_to_01(vec4 ucrect, vec2 uv) {
    return vec2(1.0, 2.0);
}
vec4 sfx_fs_output_uv_quarter(vec2 uv, vec4 color) {
    vec4 result = color;
    return result;
}
int trap(){if(true){whatever}}
 void main () {                                    
    vec2 uv = v_uv0;                                  
    vec4 color = texture2D(texture, uv);              
    gl_FragColor = color;
}               `;

const blocks=source.split(/((?:vec4|vec3|vec2|float|int|void)\s+[\w]+\s*\(.*?\))/gs);
console.log("Header");
console.log(blocks.shift());
for(let i=1;blocks.length;i++){
  console.log("Function #"+i);
  console.log(blocks.shift()+blocks.shift());
}

添加int trap(){if(true){whatever}} fake函数是为了表明这种方法不必担心嵌套的花括号。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65367401

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档