在SO上有很多这些问题,但是我没有通过将矢量坐标提取到整数值来找到这种情况。
我正在解析当前字符串:
“AT(1,1)ADDROOM RM0001”
我需要获取(#,#)之间的数字并将它们存储为整数。
我尝试的一个解决方案是获取第一个'('。读入字符串直到满足逗号,然后再次读取直到最后')'的索引。我尝试的另一个解决方案是找到','并在遇到括号之前获取字符串之前和之后。
我一直觉得这很容易出错。我觉得如果从字符串中读取,有一种更简单的方法。我在研究Regex。
答案 0 :(得分:4)
这是你需要的正则表达式:
\((-?\d+)\s*,\s*(-?\d+)\)
你可以像这样使用它:
var match = Regex.Match("some string (1234, -5678)", @"\((-?\d+)\s*,\s*(-?\d+)\)")
var x = match.Groups[1].Value;
var y = match.Groups[2].Value;
x
和y
将是向量的两个组成部分。
说明:
\(
左括号(-?\d+)
首先捕获捕获向量第一个组成部分的组。 -
是可选的(因此正和负整数都匹配)后跟一个或多个数字(\d
)。同样的事情后来在正则表达式中再次出现以捕获第二个组件\s*
这允许数字和逗号之间的任意数量的空格\)
右括号有关较低级别的说明,请转到https://regex101.com/r/PnwBJS/1并查看"解释"部分。
答案 1 :(得分:3)
这是一个简短的程序,分别捕获两个数字:
using System;
using System.Text.RegularExpressions;
public class Test
{
public static void Main()
{
string s = "AT (1,1) ADDROOM RM0001";
Regex r = new Regex(@"\((\d+)[^\d]+(\d+)\)");
MatchCollection mc = r.Matches(s);
var firstNumber = mc[0].Groups[1].Value;
var secondNumber = mc[0].Groups[2].Value;
}
}
<强>解释强>
\(
匹配左括号(\d+)
匹配一个数字;一个或多个数字[^\d]+
匹配非数字;一个或多个字符(\d+)
匹配一个数字;一个或多个数字\)
匹配关闭
括号答案 2 :(得分:1)
好的Regex在这里是最简单的方法,但你无论如何都要过滤它,因为它会提取我想的括号外的数字(我不太了解Regex), private void createLayout() {
ScrollView objScrollView = new ScrollView(this);
ViewGroup.LayoutParams objLayoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
objScrollView.setLayoutParams(objLayoutParams);
RelativeLayout objParentLayout = new RelativeLayout(this);
RelativeLayout.LayoutParams objParentParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
int intId = 100;
int intLeft = 0;
for (int i = 0; i < arrobjSeats.size(); i++) {
Seat objSeat = arrobjSeats.get(i);
RelativeLayout objItemLayout = new RelativeLayout(this);
RelativeLayout.LayoutParams objItemParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
objItemParams.setMargins(objSeat.getIntTop() + 30, objSeat.getIntLeft() - 110, 0, 10);
intLeft = objSeat.getIntTop();
ImageView imgSeat = new ImageView(this);
imgSeat.setImageResource(R.drawable.ic_airline_seat_recline_normal_black_24dp);
imgSeat.setColorFilter(Color.parseColor(objSeat.getStrSeatColor()), android.graphics.PorterDuff.Mode.SRC_IN);
imgSeat.setPadding(5, 5, 10, 25);
imgSeat.setId(intId++);
RelativeLayout.LayoutParams objImageParams = new RelativeLayout.LayoutParams(120, 80);
objImageParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
TextView txtSeatName = new TextView(this);
RelativeLayout.LayoutParams objTextParams = new RelativeLayout.LayoutParams(120, RelativeLayout.LayoutParams.WRAP_CONTENT);
objTextParams.addRule(RelativeLayout.ALIGN_BOTTOM, imgSeat.getId());
txtSeatName.setPadding(5, 10, 5, 5);
txtSeatName.setTextColor(Color.parseColor(objSeat.getStrSeatColor()));
txtSeatName.setText(objSeat.getStrSeatName());
txtSeatName.setGravity(Gravity.CENTER);
txtSeatName.setTextSize(16);
objItemLayout.setTag(i);
objItemLayout.addView(imgSeat, objImageParams);
objItemLayout.addView(txtSeatName, objTextParams);
objItemLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int intPosition = (int) v.getTag();
Seat objSeat = arrobjSeats.get(intPosition);
Toast.makeText(SeatActivity.this, "Seat=>" + objSeat.getIntSeatId() + "=>" + objSeat.getStrSeatName(), Toast.LENGTH_SHORT).show();
}
});
objParentLayout.setBackgroundColor(Color.CYAN);
objParentLayout.addView(objItemLayout, objItemParams);
System.out.println("Final Color=>" + objSeat.getStrSeatColor());
}
objScrollView.addView(objParentLayout, objParentParams);
relativeLayout.addView(objScrollView);
}
是一个整数的正则表达式数字,如果你决定这样。
另一种方法是您描述的只是过滤字符串然后将其解析为整数。
我能想到的最后一种方法是使用linq,然后解析为整数。
这是我为你的字符串做的正则表达式方法:
\d+
然后你只需要根据需要解析数组中的字符串。
答案 3 :(得分:1)
就正则表达式来说,这个案例看起来相当微不足道,但我知道正则表达式可能难以包围,所以我将详细介绍它。
在正则表达式中,数值可以由\d
表示。我假设你想要捕获大于9的坐标,所以我们将使用\d+
来捕获多个数字。
对于其余部分,逗号只是一个文字,并且在不在特定结构中使用时,它在正则表达式中没有任何特殊功能。 Unescaped brackets become capture groups,因此需要在\
之前放置文字括号。这里需要两个捕获组,每个捕获组围绕一个数字。
这样,您的(#,#)
作为正则表达式将成为\((\d+),(\d+)\)
。文字开头括号,一个包含一个或多个数字字符的捕获组,一个文字逗号,另一个数字字符捕获组,最后是字面结束括号。
然后,它只是获取捕获组并将其解析为整数。请注意,由于我们100%确定这些组的内容是一个或多个数字符号,因此不需要TryParse
,因此如果正则表达式匹配,则解析将始终成功。
String str ="AT (1,1) ADDROOM RM0001";
// Double all backslashes in the code, or prefix the quoted part with @
Regex coords = new Regex("\\((\\d+),(\\d+)\\)");
MatchCollection matches = coords.Matches(str);
if (matches.Count > 0)
{
Int32 coord1 = Int32.Parse(matches[0].Groups[1].Value);
Int32 coord2 = Int32.Parse(matches[0].Groups[2].Value);
// Process the values...
}
当然,如果要处理多个匹配项,可以使用foreach
循环遍历MatchCollection
的内容。
[编辑]
As pointed out by Sweeper,如果您想捕获正数和负数,捕获组应该变为(-?\d+)
。问号表示一个可选组件,这意味着在它之前可以有0或1个文字-
字符。这会给:
\((-?\d+),(-?\d+)\)
如果您想在这些坐标和括号/逗号之间留出空格,您还需要在组,括号和逗号之间添加一些\s*
。 *
是一个修饰符(如+
和?
),表示在它之前出现零个或多个元素。 \s
是&#34;空白&#34;的简写,就像数字\d
一样。
这个更宽松的版本将是
\(\s*(-?\d+)\s*,\s*(-?\d+)\s*\)
答案 4 :(得分:0)
假设你有任意数量的积分,你可以使用这样的东西。它几乎肯定不是很有效,但除非你处理它们,否则它可能并不重要:
const string s = "AT (35,200) ADDROOM RM0001";
var numbers = s.Split(' ')[1]
.Replace("(", string.Empty)
.Replace(")", string.Empty)
.Split(',').Select(int.Parse);