我正在学习awk编程语言,并且在这里遇到了问题。
我有一个文件(awk.dat),内容如下:
awk 'BEGIN{RS="*, *";ORS="<<<---\n"} {print $0}' awk.dat
我正在使用以下命令:
awk: run time error: regular expression compile failed (missing operand)
*, *
FILENAME="" FNR=0 NR=0
返回错误:
awk 'BEGIN{RS=" *, *";ORS="<<<---\n"} {print $0}' awk.dat
同时,如果我使用以下命令:RS=" *, *"
,则会给我所需的结果。
我需要理解这一部分:*
,双引号和,
前的Lorem ipsum dolor sit amet<<<---
consectetur adipiscing elit.
Maecenas pellentesque erat vel tortor consectetur condimentum.
Nunc enim orci<<<---
euismod id nisi eget<<<---
interdum cursus ex.
Curabitur a dapibus tellus.
Lorem ipsum dolor sit amet<<<---
consectetur adipiscing elit.
Aliquam interdum mauris volutpat nisl placerat<<<---
et facilisis.
<<<---
之间的空格的含义,因为它会引发错误。
预期输出:
public static void Main(string[] args)
{
string TrackingNumber1;
string TrackingNumber2;
string TrackingNumber3;
Console.WriteLine("Enter First Tracking Number:");
TrackingNumber1 = Console.ReadLine();
Console.WriteLine("Enter Second Tracking Number:");
TrackingNumber2 = Console.ReadLine();
Console.WriteLine("Enter Third Tracking Number:");
TrackingNumber3 = Console.ReadLine();
}
public class UspsService
{
//Base URL for USPS Address and Zip Code validation API
private const string baseURL = "http://testurl.com";
//Web client instance.
private WebClient wsClient = new WebClient();
//User ID obtained from USPS.
public string usps_UserID = "";
private string GetDataFromSite(string uspsRequest)
{
string strResponse = "";
//Send the request to USPS.
byte[] responseData = wsClient.DownloadData(uspsRequest);
//Convert byte stream to string data.
foreach (byte oItem in responseData)
strResponse += (char)oItem;
return strResponse;
}
//method that builds the track request, and sends returns the formatted string to send to USPS endpoint
public string TrackRequest(string trackingNumber1, string trackingNumber2, string trackingNumber3)
{
string strResponse = "", strUSPS = "";
strUSPS = baseURL + "?API=TrackV2&XML=<?xml version =\"1.0\" encoding =\"utf-8\"?>";
strUSPS += "<TrackRequest USERID=\"" + usps_UserID + "\">";
strUSPS += "<TrackID ID=\"" + trackingNumber1 + "\"> </TrackID>";
strUSPS += "<TrackID ID=\"" + trackingNumber2 + "\"> </TrackID>";
strUSPS += "<TrackID ID=\"" + trackingNumber3 + "\"> </TrackID>";
strUSPS += "</TrackRequest>";
//Send the request to USPS.
strResponse = GetDataFromSite(strUSPS);
Console.WriteLine(strResponse);
return strResponse;
}
谢谢。
答案 0 :(得分:3)
"[space1]*,[space2]*"
是正则表达式,它与以下字符串匹配:
零个或多个空格(space1)后跟一个逗号,然后是零个或多个空格(space2)
第一个"*,[space]*"
是错误的,因为*
在正则表达式中具有特殊含义。这意味着将匹配的组/字符重复零次或多次。您不能一开始就将其放置。
答案 1 :(得分:1)
请注意,根据POSIX,RS
被定义为单个字符,而不是正则表达式。
RS
字符串值的第一个字符应为输入记录分隔符;默认情况下为。如果 RS
包含多个字符,则结果不确定。如果RS
为空,则记录由由加上一个或多个空行组成的序列分隔,开头或结尾的空行在输入的开头或结尾不应导致空记录,并且不管 FS
的值是什么,都应该始终是字段分隔符。
这意味着RS=" *, *"
导致不确定的行为。
实现POSIX扩展的其他版本的awk,可能对RS
的含义采用不同的方法。例如GNU awk和mawk。两者都将RS
实现为正则表达式,但是两种实现都略有不同。
| RS | awk (posix) | gawk | mawk |
|------+--------------+------------------+------------------|
| "*" | "<asterisk>" | "<asterisk>" | "<asterisk>" |
| "*c" | undefined | "<asterisk>c" | undefined |
| "c*" | undefined | "","c","ccc",... | "","c","ccc",... |
c is any character
根据mawk,以上RS="*, *"
是无效的正则表达式,因此应该解释OP的错误。
$ echo "abc" | ./mawk '/*c/'
mawk: line 1: regular expression compile failed (missing operand)
GNU awk: GNU awk手册规定以下内容:
使用
gawk
时,RS
的值不限于一个字符的字符串。它可以是任何正则表达式(请参见Regexp)。 (c.e.)通常,每个记录都在与正则表达式匹配的下一个字符串处结束;下一条记录从匹配字符串的末尾开始。
要了解
<星号>
*
这个符号表示前面的正则表达式应该重复多次以找到匹配项。例如,ph*
将*
符号应用于前面的h
,并寻找一个p
的匹配项,后跟任意数量的h
。如果不存在p
,则这也仅与h
相匹配。要了解
*
的工作原理,有两点要注意。首先,*
仅适用于单个前面的正则表达式组件(例如,在ph*
中,它仅适用于h
)。要使*
适用于较大的子表达式,请使用括号:(ph)*
匹配ph
,phph
,phphph
等。第二,
*
找到尽可能多的重复。如果要匹配的文本是phhhhhhhhhhhhhhooey
,则ph*
匹配所有h
。
但是必须指出的是:
在
POSIX awk和gawk中,当在正则表达式中没有任何正则表达式时,*
,+
和?
运算符就代表自己。例如,/+/
与文字加号匹配。但是,许多其他版本的awk会将这种用法视为语法错误。
因此,设置RS="*, *"
意味着它将与字符串"*,"
,"*, "
,"*, "
,...匹配。
$ echo "a,b, c" | awk 'BEGIN{RS="*, *"}1'
a,b, c
$ echo "a*,b, c" | awk 'BEGIN{RS="*, *"}1'
a
b, c
mawk::GNU awk的手册规定如下:
12。多行记录
由于mawk
将RS
解释为正则表达式,因此多行记录很容易。来源:
man mawk
但是
11。拆分字符串,记录和文件
Awk程序使用相同的算法将字符串拆分为以下数组:split()
,并记录到FS
的字段中。 mawk使用基本上相同的算法将文件拆分为RS
上的记录。
Split(expr,A,sep)
的工作方式如下:
- 如果
sep = " "
(单个空格),则从expr
的正面和背面修剪,并且 sep
变为。 mawk将 定义为正则表达式 /[ \t\n]+/
。否则,sep
被视为正则表达式,除外,元字符除外 对于长度为1的字符串会被忽略,例如split(x, A, "*")
和split(x, A, /\*/)
相同。来源:
man mawk
手册不没有提及应如何解释以元字符开头的正则表达式(例如“ * c”)
注意:在POSIX awk中,我触及了GNU awk部分,因为根据POSIX,形式为"*, "
的正则表达式会导致未定义的行为。 (这与将RS
定义为RS
始终不是POSIX awk中的ERE无关)
awk实用程序应使用扩展的正则表达式符号(请参见XBD Extended Regular Expressions)
和
*+?{
除在方括号表达式中使用时,,<加号>, 和 应该是特殊的(请参见RE方括号表达式)。 以下任何用途都会产生不确定的结果:
- 如果这些字符首先出现在ERE中,或者紧随未转义的
, , 或 - 如果
不是有效间隔表达式的一部分(请参阅匹配多个字符的ERE)
答案 2 :(得分:1)
请您尝试一次。
awk '{gsub(", ","<<<---" ORS)} 1;END{print "<<<---"}' Input_file