数据人与超自然意识 发表于 2024-9-5 13:50:26

05 Windows批处理中的字符串和布尔数据类型

要相识在批处理中分配数据类型的第一件事是批处理不答应分配数据类型。全部批处理变量都是等效的。从本质上讲,生存数字、文本甚至布尔值的变量之间没有区别。但是,设置为数字的变量可以被视为数字,我们将在背面的文章中重点讨论这些数据类型。
在本文中,在形貌了全部批处理数据类型之后,我们将学习字符串和字符变量。还将使用子字符串和文本更换的方法进一步探索字符串。布尔值不是由批处理的创建者设计的,但是我们将向您展示怎样构建和使用这种有效的数据类型。
常见的数据类型

很多编程语言不仅答应而且要求在为每个变量赋值或以任何方式使用它之前将其声明为特定的数据类型。差别的语言有差别的数据类型,这里列出来一些常用的数据类型列表:

[*]字符 --- 单个字母数字字符
[*]字符串 --- 0到多个字母数字字符
[*]整数 --- 正负整数
[*]浮点数 --- 带小数点的数字
[*]布尔型 --- true或false
不管申明数据类型是好照旧坏,批处理变量都没有声明详细的数据类型。当解释器第一次发现一个新的变量名时,它就会无中生有。这种做法确实有很大的机动性,但它可能是棘手和危险的。一个被使用了十几次的变量的一个拼写错误的实例被解释器以为是一个完全差别的变量,编译器不会捕捉到这个错误。相反,它被视为一个可能什么都解决不了的新变量。
变量可以被赋值为整数,而且可以对其执行算术运算。然后可以为同一变量分配文本并将其视为字符串。这也意味着可能会偶然中对包含字符串的变量执行算术,但好处是,在将数字写入控制台或陈诉时,可以很轻易地将其视为字符串,而无需进行任何类型的转换。
尽管您不能分配数据类型,但是您可以创建变量并将它们视为类型之一,但是—我必须强调这一点是每个批处理变量的底层结构现实上只是一些无法形貌的内存字节。
字符

一个字符仅仅是一个字节的文本;在批处理的世界中,可以把它看作一个非常短的字符串,由于它被看成任何只有一个字符的字符串一样对待。
字符串

字符串是任意长度的文本,包含字母字符、数字和/或特殊字符。下面的下令将aString变量设置为一个5个单词的字符串:
set aString=Awesome Batch Code Dares Excellence包括嵌入的空格在内,它的长度总计为35个字符,大概用程序员的话说,就是字节。
很多特殊字符,如美元符号和英磅符号,可以显式地包含在字符串中,但其他字符,如百分号,不能包含在字符串中,由于它们在批处理中有特定的用途。在背面的文章中,我们将讨论转义字符,即怎样答应在字符串中包含全部字符,但是现在,要理解解释器在遇到字符串中的感叹号时不会中断,但是您可能看不到预期的结果。例如,赋给这个变量的值的最后一个字符是感叹号:
rem 开启延迟扩展
setlocal EnableDelayedExpansion

set aString=Awesome Batch Code Dares Excellence!
> con echo A String is "%aString%"下面是echo下令的结果:
A String is "Awesome Batch Code Dares Excellence"标点符号没有写入控制台,由于它没有包含在字符串变量中。
注意:
正如在前面文章中提到的,我们假设延迟扩展始终是启用的。这个示例就是一个很好的例子,由于如果禁用了延迟展开,那么感叹号就只是另一个字符,而不是用于剖析变量的分隔符。该字符将作为值的一部分包含,并将与其余文本一起写入控制台。可以或许将感叹号视为简朴的文本可能是禁用延迟扩展的唯一好处。与延迟扩展提供的功能相比,这个微不足道的优势显得微不足道,这就是我保举普遍使用延迟扩展的原因。
在背面的文章中,我们将讨论怎样将字符串和其他数据类型写入文件,但在这里,我将解释怎样构建、毗连、子字符串和操作字符串。
构建和毗连

前面的示例使用单个set下令将值Awesome Batch Code dare Excellence分配给一个变量。下面的六行执行雷同的任务:
set a=Awesome
set b=Batch &
set c=Code
set d=Dares
set e= Excellence
set aString=%a% %b%%c% %d%%e%在实践中,这种方法对于构建字符串来说非常低效,但是它很好地演示了毗连的原理。
由字母表的前五个字母定义的变量分别被设置为一个单词。然后在最后一行,全部五个变量被剖析并毗连在一起以创建aString。注意结果中的四个嵌入空格。一个来自批处理之后的尾随空格,另一个来自Excellence之前的前导空格,另外两个嵌入在最后一个set下令中。
前面的例子展示了怎样通过毗连其他字符串来创建字符串,但你也可以在现有字符串上添加其他文本:
set longText=This field contains a brutal run-on sentence and if its prose
set longText=%longText% were to be typed into a single line the reader would
set longText=%longText% be forced to scroll way over to the right to read what
set longText=%longText% you are reading now and then scroll way back to the
set longText=%longText% left after mercifully getting to this period.在这里,一个字符串被附加了四次额外的文本,以创建一个非常长的字符串。这种方法是我创建长字符串变量的首选方法,但是您也可以使用“延续字符”或插入符号(^)来完成雷同的任务。当解释器看到行尾的插入符号时,它会将下一行附加到该行:
set longText=This field contains a brutal run-on sentence and if its prose ^
were to be typed into a single line the reader would be forced to scroll way^
over to the right to read what you are reading now and then scroll way back ^
to the left after mercifully getting to this period.在这个例子中,三个插入符号被用来组成一个四行set下令。第一行和第三行在插入符号前面有一个空格,它们的下一行从第一个字节开始,导致单词之间有一个空格。为了演示做同样事情的另一种方法,第二个插入符号紧跟着单词way,下一行在下一个单词之前有一个空格,over。结果是一长串单词,全部由一个空格分隔。
我并不保举这种使用方式,原因很简朴,它会破坏我们的缩进编码风格。我将大多数下令缩进两个或多个空格,如set下令的第一行所示,但是背面一行开头的任何空格都被以为是附加文本的一部分。这现实上意味着这些行必须左对齐。
重要:
我把“延续字符”放在引号里,由于这是一个大略的简化。插入符号现实上是一个转义字符。
子串

任何称职的语言都会支持检索字符串一部分的子字符串函数,批处理也可以胜任这项任务。对于接下来的几个例子,让我们思量像之前一样设置aString变量:
set aString=Awesome Batch Code Dares Excellence子字符串函数必要两个数字,偏移量或起始位置以及所需文本的长度。令人惊讶的是,批处理使用了在现代语言中占主导地位的零偏移(下标从0开始数),而不是20世纪语言中更常见的一偏移。这意味着第一个字节是位置0(不是1),第二个字节是位置1,第100个字节是位置99,以此类推。
子串的语法有点鸠拙。这个变量通常用百分号剖析,但是在结束的百分号前面有一个冒号、一个波浪号、偏移量、一个逗号,最后是长度。因此,以下语法返回aString变量的前三个字符:
set substring=echo %aString:~0,3%0的偏移量告诉解释器从第一个字节开始,长度定义为3,导致文本Awe被分配给subString。
下面的代码从字符串的第一个单词some中提取文本:
set subString=%aString:~3,4%我们必要从第四个字节开始,这是一个零偏移量3。如果您发现零偏移量令人狐疑,请将偏移量视为子字符串之前的字节数。更明显的是,长度是4。
下面是用硬编码的to和两个空格组合在一起的两个子字符串:
set phrase=%aString:~15,3% to %aString:~8,5%第15个字节是Code中的大写C,因此第一个子字符串是单词的剩余三个字节。第八个字节是Batch前面的空格,所以接下来的五个字节包含了整个单词。结果是对原始字符串的重新解释:ode to Batch。
如果没有定义长度,解释器返回字符串的剩余部分。为了演示,下面的子字符串没有长度,前面没有逗号。偏移量对应于35个字节变量中之前的25字节:
set subString=%aString:~25%结果是subString被分配了字符串Excellence,即原始字符串的最后10个字节。
偏移量为负数

请注意以下示例中的负偏移量。风趣的是,这也将 Excellence 分配给变量:
set subString=%aString:~-10%负偏移量表示起始位置相对于字符串的末端,而不是开始,这意味着-10告诉解释器子字符串从字符串末端开始10个字节。由于没有给出长度,所以它返回文本的剩余部分。只要变量存在值,%aString:~-1%是检查其最后一个字节的简朴方法。
这两个下令产生雷同的ode子字符串:
set subString=%aString:~15,3%
set subString=%aString:~-20,3%第一个下令的偏移量是从原始字符串开始的15个字节,而第二个下令通过从35字节变量的末端开始盘算20个字节来找到雷同的位置。
长度为负数

负长度的工作原理与此类似。不要把它想象发展度;可以把它看作字符串末端而不是子字符串中的字节数。例如,下面的代码返回一个去掉第一个和最后一个字节的字符串:
set subString=%aString:~1,-1%你甚至可以使用负长度的负偏移量。下面提取字符串的倒数第二个字节:
set subString=%aString:~-2,-1%-2的偏移量告诉解释器从倒数第二个字节开始,-1的长度表示删除最后一个字节。
子字符串实践

在批处理中检索子字符串的一个很好的特性是,如果调用超出字符串长度的子字符串,则返回null。因此,解释器在遇到%aString:~99,1%的35字节字符串时不会崩溃,也不会返回一个空格。相反,它只返回一个空字符串。这是一种方便的确定字符串长度的方法,不用担心编译代码中普遍存在的空指针异常。如果第36个字节等于null(即"%aString:~35,1%" equ ""),但第35个字节有值,则字符串的长度恰好是35字节。
但是,此语法仅在对已填充的字符串进行子字符串处理时有效。正如我刚才提到的,如果字符串的长度在1到35个字节之间,%aString:~35,1%剖析为空,当然,如果字符串的长度在36个字节或更长,它将剖析到第36个字节。但是,如果字符串为空或设置为null,则%aString:~35,1%剖析为~35,1或冒号和末端分隔符之间的全部内容。同样,由于这个问题,当尝试检查空字符串的最后一个字节时,%aString:~-1%剖析为~-1,而不是您可能期望的null。
现在您知道了怎样从另一个字符串中提取字符串的任何部分,但是在前面的示例中,全部的偏移量和长度都是硬编码的。通常,这两个数字将是变量。在下面的例子中,偏移量和长度被定义为定名的变量,并在第三个下令中使用:
rem 不要忘记开启延迟扩展

set offset=15
set length=3
set subString=!aString:~%offset%,%length%!包含偏移量和长度的百分号起首将这些变量剖析为它们的数值。然后加上感叹号,这样!aString:~15,3!剖析为我们熟悉的ode,这是实现延迟扩展的另一个乐成。
在背面的文章中,我将讨论算术运算,在完成之后,您将可以或许盘算生存整数值的变量,这些整数值将用作偏移量和长度来查找子字符串。
文本更换

批处理还有一个方便的机制,可以用其他文本更换字符串的全部或部分。例如,假设以下变量包含这个不保举的文件名:
set filNm=File_Name_With_Underscores.docx如果不喜欢这个文件名,可以将下划线更改为破折号。在后续文章中,我们也将先容重定名文件的保举下令,但这里我将讨论怎样构建一个包含新文件名的变量。
文本更换语法类似于用于子字符串的语法。变量和冒号像从前一样被百分号困绕,但是现在没有波浪号了。相反,冒号之后是要搜刮和更改的文本,背面跟着等号分隔符,最后是更换文本:
set newFilNm=%filNm:_=-%每个下划线字符(_),而不仅仅是遇到的第一个下划线字符,都被更改为破折号(-),从而产生File-Name-With-Underscores.docx。注意不要更改过多的文本。
看看这个文件名,将“下划线”改为“破折号”也是有意义的。荣幸的是,批处理不要求目标文本和更换文本的长度雷同,所以这个额外的下令进一步将这个变量的值更新为File-Name-With-Dashes.docx:
set newFileNm=%newFileNm:underscor=Dash%由于两个单词都以es结尾,所以我使用单数 Dash 作为更换文本,目标文本是 underscor,这不是一个完整的单词。另外,请注意,在变量的值中,Underscores 是大写的,而在更换语法中,underscor 是小写的。非常重要的是,批处分析进行不区分巨细写的更换。目标文本可以是任何一种情况,甚至可以是混合情况,对结果没有影响,但是更换文本将完全按照下令中输入的方式使用。因此,%newFilNm:UNDERscor=Dash%在功能上与上一个下令中的变量剖析雷同,但是%newFilNm:UNDERscor=DASH%将产生一个新的文件名File-Name-With-DASHes.docx。
这很奥妙,但前面两个下令显示了两种差别的赋值方法。第一个将修改后的filNm值赋给newFilNm,使filNm保持不变。第二个下令将newFilNm重新分配给它自己,以便它的最终值反映两个文本更换。这两种方法为您提供了机动性,可以就地更改变量的值,也可以维护两个变量,一个包含旧文本,一个包含新文本。
还可以使用延迟扩展将目标文本(target)和更换文本(repl)转换为变量。这里有一个例子:
set targ=Love
set repl=Hate
set aString=I Love Broccoli
set aString=!aString:%targ%=%repl%!结果是字符串“I Hate Broccoli”。
文本搜刮是文本更换语法的一个很好的应用。在后续文章中,我们将比较和对比确定一个字符串是否是另一个字符串的一部分的两种方法。findstr下令工作得很好,但是基于前面语法的方法执行时间很短。剧透告诫:文本搜刮逻辑将搜刮到的文本更换为null,并将结果与原始文本进行比较。如果它们差别,则找到了文本。
布尔值

布尔值不停存在于编译语言中,有两种,而且只有两种可能的状态:真(true)或假(false)。一旦设置好,您就可以单独使用它们作为if下令中的条件子句,将其盘算为true或false,从而确定是否应该执行代码块。批处理并不显式地支持布尔值,但是只要稍微使用一点技巧,您就可以创建它们。
“God.txt存在吗?”在前面的文章中,我展示了怎样使用if下令来确定文本文件是否存在:
if exist D:\Batch\God.txt (
   set god=Found
) else (
   set god=NotFound
)根据文件在某一时候的状态将变量设置为Found或NotFound。然后可以在未来扣问god变量,以确定god .txt在较早的时间是否存在。它可以运行,但有点笨重;布尔值将提供更优雅的解决方案。然后,您可以轻松地在整个代码中多次引用布尔值,甚至可能重置它。
设置和盘算布尔值

在批处理中,像全部变量一样,布尔值现实上只是一些文本,但是这些文本可以被看作为true或false。按照惯例,我总是在布尔变量名的前面加上小写b和大写字符,以使其作为布尔值突出。(一个更详细和形貌性的选项是以bool文本开头。)让我们复制上一个示例中的逻辑,唯一的区别是变量god被布尔值bGod更换,如果找到God .txt,则将其设置为true,如果未找到则设置为false:
if exist D:\Batch\God.txt (
   set bGox=true==true
) else (
   set bGox=false==x
)在其他语言中,布尔值被显式设置为true或false。例如,一个有效的Java下令是bGod = true;但是前面的关于批处理中的布尔值的set下令看起来有点差别;特别地,每个都有三个等号。第一个仅仅是用来赋值,另外两个是用来指定值。当 if 下令的条件子句为true时,我们将bGod设置为truetrue;如果不是,则falsex为值。这当然看起来很奇怪,但是现在这个变量,虽然从技术上讲仍然只是文本,但可以作为另一个if下令的条件子句进行判断,如下所示:
if %bGod%> con echo Let us pray.如果bGod被设置为我们以为的true,解释器将If %bGod%剖析为If true == true。变量包含一个相称运算符,双等号,两边的值雷同。(不要问操作符周围的空格,但这是解释器看到的。)将全部这些放在 if 下令之后,它的盘算结果为true。
但是,如果将变量设置为我们以为的false,则该下令将被剖析为If false == x,这将比较两个明显差别的值,从而导致If下令背面的代码不执行。
带布尔值的if下令也可以与not子句一起使用:
if not %bGod%> con echo Live every day to the fullest.如果文本(if not %bGod%)剖析为If not true == true,则盘算结果 not true 或 false。但是当文本剖析为双否定if not false == x时,它的盘算结果为not false或not true,并将文本写入控制台。
布尔值转换为字符串

我选择truetrue作为true的值,但是xx或0 == 0也可以,而且必要更少的按键。即使falsefalse也会求值为真,但这并不难。同样,falsex可以包含任意两个差别的字符串,但我选择了这两个值,以便文本true或false在布尔值的前面。布尔变量的结构答应您在编译代码中模拟布尔值的另一个特性——将布尔值转换为字符串。
作为结构化的,您可以将批处理中的布尔值转换为字符串true或false,只需去掉两个等号之后和包含的全部内容。当我们在看到for下令时,我将展示它是怎样工作的,但是现在,下面这行代码将截断多余的文本:
for /F "delims==" %%b in ("%bGod%") doset bStrGod=%%b在对一个有效的布尔值执行此下令后,名为bStrGod的布尔字符串变量将包含true或false。
如果布尔变量的前缀是b,那么用b作为布尔字符串变量的前缀可能是有意义的。
总结

字符串在批处理中无处不在,在本文中,我们详细先容了怎样构建和毗连它们。子字符串和文本更换是全部批处理程序员都应该掌握的两个强盛而有效的工具,尽管它们的语法很深奥。布尔值并不是那么普遍,但我盼望我展示了这种未充分利用的数据类型的有效性。
在下一篇文章中,我们将继续讨论数据类型,深入研究数值数据类型。我将详细先容三种差别进制的整数和浮点数,为探索批处理中怎样处理算术提供了一个很好的机遇。
本文由博客一文多发平台 OpenWrite 发布!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 05 Windows批处理中的字符串和布尔数据类型