如何分隔中间有符号的字符串

How to separate a string with a sign in the middle

我正在编写需要获取二项式表达式的两个变量的代码。我想知道有没有办法把中间有符号的字符串分成两个子串

e.g. (x+y)^3 to var1=x and var2=y or (qwerty-asdf)^12 to var1=qwerty and var2=asdf

我试过这样做:

character(100) :: str, var
var=' ' 
do i=1,len(str)
    if (((str(i:i) == "+") .or. (str(i:i) == "-")) .or. &
    ((str(i:i) >= "a") .and. (str(i:i) <= "z"))) &
    var=trim(var)//trim(str(i:i))   
end do

但是唯一被删除的字符是括号和幂。

我看待我的问题的另一种方式是,如果我知道符号所在的字符串长度,那么我可以这样做:

character(100) :: str, var
    var=' ' 
    do i=1,len(the_unknown_string_length)
        if ((str(i:i) >= "a") .and. (str(i:i) <= "z")) &
        var=trim(var)//trim(str(i:i))   
    end do

虽然,我也不知道如何才能得到符号出现的具体字符串长度。

我不会乱用循环 - 我会使用可用的内部函数。像

ijb@ijb-Latitude-5410:~/work/stack$ cat binom.f90
Program binom

  Implicit None

  Character( Len = 100 ) :: expression

  Character( Len = : ), Allocatable :: var1, var2

  Write( *, '( a )' ) 'Expression?'
  Read ( *, '( a )' ) expression

  Call split_it( expression, var1, var2 )

  If( Len( var1 ) /= 0 .And. Len( var2 ) /= 0 ) Then
     Write( *, '( a, a, t20, i0 )' ) 'Var1 = ', var1, Len( var1 )
     Write( *, '( a, a, t20, i0 )' ) 'Var2 = ', var2, Len( var2 )
  Else
     Write( *, * ) 'No + or - in the string'
  End If

Contains

  Subroutine split_it( expression, var1, var2 )

    Implicit None

    Character( Len = * ),              Intent( In    ) :: expression
    Character( Len = : ), Allocatable, Intent(   Out ) :: var1
    Character( Len = : ), Allocatable, Intent(   Out ) :: var2

    Integer :: split_pos
    Integer :: paren_pos

    split_pos = Scan( expression, '+-' )

    If( split_pos /= 0 ) Then

       var1 = Trim( Adjustl( expression( :split_pos - 1 ) ) )
       paren_pos = Scan( var1, '(' )
       var1 = Trim( Adjustl( var1( paren_pos + 1: ) ) )

       var2 = Trim( Adjustl( expression( split_pos + 1: ) ) )
       paren_pos = Scan( var2, ')' )
       var2 = Trim( Adjustl( var2( :paren_pos - 1 ) ) )

    Else

       Allocate( Character( Len = 0 ) :: var1 )
       Allocate( Character( Len = 0 ) :: var2 )

    End If

  End Subroutine split_it
  
End Program binom
ijb@ijb-Latitude-5410:~/work/stack$ gfortran --version
GNU Fortran (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

ijb@ijb-Latitude-5410:~/work/stack$ gfortran -Wall -Wextra -fcheck=all -std=f2008 -g binom.f90 
ijb@ijb-Latitude-5410:~/work/stack$ ./a.out
Expression?
(x+y)^3
Var1 = x           1
Var2 = y           1
ijb@ijb-Latitude-5410:~/work/stack$ ./a.out
Expression?
(qwerty-asdf)^12
Var1 = qwerty      6
Var2 = asdf        4
ijb@ijb-Latitude-5410:~/work/stack$ ./a.out
Expression?
( aag + fg ) ^98
Var1 = aag         3
Var2 = fg          2
ijb@ijb-Latitude-5410:~/work/stack$ ./a.out
Expression?
wibble
 No + or - in the string