定位字符串中特定的发生事件并将其替换

我有一个字符串中包含多个 /,我试图将这个字符串转换为 LaTeX 代码。基本上,(a)/(b) 变成了 \\dfrac{a}{b}

困难在于 (a) 和/或 (b) 可能还包含其他 /。

为了尊重括号的平衡,我希望从左到右替换 /,并根据周围的内容相应地进行替换。我尝试了一下,但不知道如何定位特定的 / 并进行替换。使用位置和长度参数似乎非常复杂。

function ToFrac (s)
    while s:find ("/") ~= nil
    do

    -- Replace : \dfrac{}{}/() -> \dfrac{\dfrac...}{}
    if ( s:find ( '\\dfrac%b{}%b{}/%b()' , j ) ~= nil )
    then
    x,y,num,den = s:find( '(\\dfrac%b{}%b{})/(%b())' )
    den = den:gsub( '.(.+).' , '%1' )
    s = s:gsub( '(\\dfrac%b{}%b{})/(%b())',
                            "\\dfrac{"..num.."}{"..den.."}" , 1 )
    end

    print ('### -- ', s)

    -- Replace : ()/\dfrac{}{} -> \dfrac[}]{\dfrac...}
    if ( s:find ( '(%b()/\\dfrac%b{}%b{}' ) ~= nil )
    then
    x,y,num,den = s:find( '((%b())/(\\dfrac%b{}%b{})' )
    num = num:gsub( '.(.+).' , '%1' )
    s = s:gsub( '((%b())/()\\dfrac%b{}%b{})',
                            "\\dfrac{"..num.."}{"..den.."}" , 1 )
    end

    print ('### -- ', s)

    -- Replace : ()/() -> \dfrac{}{}
    if ( s:find ( '%b()/%b()' , 1 ) ~= nil )
    then
        x,y,num,den = s:find( '(%b())/(%b())' )
        num = num:gsub( '.(.+).' , '%1' )
        den = den:gsub( '.(.+).' , '%1' )
        s = s:gsub( '(%b())/(%b())',
                        "\\dfrac{"..num.."}{"..den.."}" , 1 )
        Done = true
    end

    print ('### -- ', s)

    end -- while

    return (s)

end

s = "((a)/(b))/(c)"
print (s, ToFrac(s))

s = "(a)/((b)/(c))"
print (s, ToFrac(s))

s = "(a)/(b)/(c)/(d))"
print (s, ToFrac(s))

s = "((a)/(b))/((c)/(d))"
print (s, ToFrac(s))
点赞
用户2726734
用户2726734

string.gsubreplace 参数可以是一个函数。使用该函数,你可以递归地应用替换操作到分子和分母并以此构建结果。使用 string.sub 可以从分子和分母中移除括号。

function to_frac(expr)
     return (expr:gsub('%s*(%b())%s*/%s*(%b())%s*',
         function(num, denom)
             return '\\dfrac{'..to_frac(num:sub(2,-2))..'}{'
                              ..to_frac(denom:sub(2,-2))..'}'
         end))
end

expr = ' (a )/((b) / (c))' -- \dfrac{a }{\dfrac{b}{c}}

print(to_frac(expr))

expr = '((a)/((b)/(c)))/(e)' -->\dfrac{\dfrac{a}{\dfrac{b}{c}}}{e}
print(to_frac(expr))

如果你想超越使用圆括号作为分隔符和遵守运算优先级规则,则可以尝试使用 LPeg。

2015-07-20 21:52:05
用户1847592
用户1847592
## rpattiso 的想法修改版本:

```lua
function to_frac(expr)
  local t
  return expr == '' and '' or (expr..'()'):gsub('(.-)(%b())',
    function(prefix, subexpr)
      local replace_with = ''
      if not prefix:find'^%s*/%s*$' then
        t, replace_with = {}, (not t and ''
          or t[2] and '\\dfrac{'..t[1]..'}{'..t[2]..'}'
          or '('..t[1]..')')..prefix
      elseif t[2] then
        t = {'\\dfrac{'..t[1]..'}{'..t[2]..'}'}
      end
      table.insert(t, to_frac(subexpr:sub(2,-2)))
      return replace_with
    end
  )
end

print(to_frac' (a )/((b) / (c))')   --> \dfrac{a }{\dfrac{b}{c}}
print(to_frac'((a)/((b)/(c)))/(e)') --> \dfrac{\dfrac{a}{\dfrac{b}{c}}}{e}
print(to_frac'(a)/(b)/(c)/(d)')     --> \dfrac{\dfrac{\dfrac{a}{b}}{c}}{d}
2015-07-21 00:11:09