web-dev-qa-db-ja.com

最後のドットの後に変数を2に分割します

最後のドットの後、変数を2つの小さな変数にカットする必要があります。たとえば、変数「european.union」はvara=europeanおよびvarb=unionになります。

この目的を達成するために、次のコードを使用します。

for /f "tokens=1 delims=." %%a in ("%elvariato%") do set vara=%%a
for /f "tokens=2 delims=." %%a in ("%elvariato%") do set varb=%%a

問題は、このコードが複数の「.」分割変数を管理できないことです。たとえば、変数spain is in.the.european.unionは、このコードをまったく役に立たないものにします。

vara="spain is in"varb=theが出力になりますが、vara="spain is in.the.european"varb=unionが必要です

Varスペースでは心配しないでください、私はそれらを管理することができます。

最後のドット.で変数を分割したいのですが、それを実現する方法がわかりません。トークンの総数を読み取って、N-1までのすべてのトークンをマージしようとしましたが、機能しませんでした。スクリプトによって変数が分析される前にドットの数を知ることができないと、それはちょっと難しいです。なにか提案を?

1
user866187

私の提案はPowerShellを使用することです;-)。

_$text = "spain is in.the.european.union"
$vara = $text.Substring(0, $text.lastIndexOf('.'))
$varb = $text.Split(".")[-1]
_

出力:

_PS C:\WINDOWS\system32> $vara
spain is in.the.european

PS C:\WINDOWS\system32> $varb
union
_

これをcmdスクリプトで使用するには、_%vara%_と_%varb%_を正しく設定し、cmdスクリプトでさらに使用します。

_for /f "delims=" %%a in (' powershell "$env:elvariato.Substring(0, $env:elvariato.lastIndexOf('.'))" ') do set "vara=%%a"
for /f "delims=" %%a in (' powershell "$env:elvariato.split('.')[-1]" ') do set "varb=%%a"
_

この場合、_%vara%_には_spain is in.the.european_が含まれ、_%varb%_にはunionが含まれます

説明:

  • Substring(0, $text.lastIndexOf('.'))は、文字列の先頭(_0_)から最後の_._までのすべてを取得します
  • split('.')[-1]は各ドットで文字列を分割し、作成された配列の最後の値を取得します
3
SimonS

次の(部分的にコメントされた)コードスニペットは、純粋なバッチファイルソリューションを示しています。

@ECHO OFF
rem default/expected: SETLOCAL EnableExtensions DisableDelayedExpansion
if "%~1"=="" (
  set "elvariato=spain is in.the.european.union"      asked example value
) else (
  set "elvariato=%~1"                                 supplied sample value 
)
set "_dot_pos="      
set "nodots=%elvariato:.=%"                           check for any dot presence
if "%nodots%"=="%elvariato%" goto :jjloopEnd          
set /a jj=1
:jjloop              compute last dot position (counted from the end of string)
  call set "_auxiliary=%%elvariato:~-%jj%%%"
  set "_aux_1char=%_auxiliary:~0,1%"
  if "%_aux_1char%"=="." (
      set /A _dot_pos=jj
      set /A _dot_pre=jj - 1
      goto :jjloopEnd
  )
  set /a jj+=1
  goto :jjloop
:jjloopEnd
if not defined _dot_pos (
    rem string does not contain any dot character at all
    set "vara=%elvariato%"
    set "varb="
    goto :showResults
)
call set "vara=%%elvariato:~0,-%_dot_pos%%%"
if %_dot_pos% EQU 1 (
    set "varb="
) else (
    call set "varb=%%elvariato:~-%_dot_pre%%%"
)
:showResults
rem debugging output 
echo vara="%vara%" varb="%varb%"
goto :eof

サンプル出力

==> D:\bat\SU\1302882c.bat
vara="spain is in.the.european" varb="union"

==> D:\bat\SU\1302882c.bat "."      a dot only
vara="" varb=""

==> D:\bat\SU\1302882c.bat "nodots"
vara="nodots" varb=""

==> D:\bat\SU\1302882c.bat ".leading dot only"
vara="" varb="leading dot only"

==> D:\bat\SU\1302882c.bat "trailing dot only."
vara="trailing dot only" varb=""

==> D:\bat\SU\1302882c.bat "1st.dot.2nd.dot.another.dot.more.dots"
vara="1st.dot.2nd.dot.another.dot.more" varb="dots"

リソース(必読、不完全):

1
JosefZ

これは「不正行為」である可能性がありますが、区切り文字がドット(“ .”)である限り、トリックを使用できます。文字列がファイル名であるかのように見せかけます。

setlocal enabledelayedexpansion
    ︙
for %%A in (%elvariato%) do set "vara=%%~nA" & set "varb_plus=%%~xA"
for /f "delims=. tokens=1" %%B in ("!varb_plus!") do set varb=%%B

%%~nA%%~xAは、%%Aをパス名として扱い、ベースファイル名の部分と拡張子をそれぞれ抽出します。ベースファイル名は最後のドットまでのすべてであると定義されているので、それがvaraです。拡張子は最後のドットとその後のすべて(「.txt」など)ですが、これは必要なものではありません。したがって、拡張子をvarb_plusに割り当てます—これはvarbにドットを加えたものの望ましい値です。次に、for /f "delims=. tokens=1"を使用して、ドットの後の部分を取得するのは簡単です。

%%~nA%%Aベースファイル名部分を返すため、完全な変数に/または\が含まれている場合は失敗します。 。 %%~pA%%Aのパス名部分)を見ればこれを処理できるかもしれませんが、これを行う方法はすぐにはわかりません—特にを含むことができる場合はそうです/または\